)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"8d42f9c3659a7b0100f625d057a5b51fecbd1288","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Remove neutron OO wrappers"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Removed tempest/scenario/network_resources.py and updated tests"},{"line_number":10,"context_line":"to use client results directly."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This patch was a team effort with Joshua White (IRC:jlwhite)"},{"line_number":13,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bab6814e_5edbaf1b","line":10,"updated":"2016-05-24 14:56:15.000000000","message":"Maybe add some background rationale as to why we\u0027re making this change. Commit messages are also for the log when we have to revisit changes years down the road.","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"bae16681e99d96751f553c10ebb149680c34b107","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Remove neutron OO wrappers"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Removed tempest/scenario/network_resources.py and updated tests"},{"line_number":10,"context_line":"to use client results directly."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This patch was a team effort with Joshua White (IRC:jlwhite)"},{"line_number":13,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bab6814e_ab1d2d68","line":10,"in_reply_to":"bab6814e_5edbaf1b","updated":"2016-05-24 20:06:43.000000000","message":"Done","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"8d42f9c3659a7b0100f625d057a5b51fecbd1288","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Removed tempest/scenario/network_resources.py and updated tests"},{"line_number":10,"context_line":"to use client results directly."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This patch was a team effort with Joshua White (IRC:jlwhite)"},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I3879ae24e47590d12fb09a4bb4697f139f57caf7"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bab6814e_7e931350","line":12,"updated":"2016-05-24 14:56:15.000000000","message":"Please use:\n\nCo-Authored-by: Joshua White \u003cemail@domain.com\u003e","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"bae16681e99d96751f553c10ebb149680c34b107","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Removed tempest/scenario/network_resources.py and updated tests"},{"line_number":10,"context_line":"to use client results directly."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"This patch was a team effort with Joshua White (IRC:jlwhite)"},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I3879ae24e47590d12fb09a4bb4697f139f57caf7"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"bab6814e_8b182977","line":12,"in_reply_to":"bab6814e_7e931350","updated":"2016-05-24 20:06:43.000000000","message":"Done","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"}],"tempest/scenario/manager.py":[{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"8d42f9c3659a7b0100f625d057a5b51fecbd1288","unresolved":false,"context_lines":[{"line_number":687,"context_line":""},{"line_number":688,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":689,"context_line":"        super(NetworkScenarioTest, self).__init__(*args, **kwargs)"},{"line_number":690,"context_line":"        self._router_id_use_counts \u003d dict()"},{"line_number":691,"context_line":""},{"line_number":692,"context_line":"    def _create_network(self, networks_client\u003dNone,"},{"line_number":693,"context_line":"                        routers_client\u003dNone, tenant_id\u003dNone,"}],"source_content_type":"text/x-python","patch_set":1,"id":"bab6814e_613416de","line":690,"updated":"2016-05-24 14:56:15.000000000","message":"This should just be in resource_setup() (which is essentially the end of setupClass())","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"bae16681e99d96751f553c10ebb149680c34b107","unresolved":false,"context_lines":[{"line_number":687,"context_line":""},{"line_number":688,"context_line":"    def __init__(self, *args, **kwargs):"},{"line_number":689,"context_line":"        super(NetworkScenarioTest, self).__init__(*args, **kwargs)"},{"line_number":690,"context_line":"        self._router_id_use_counts \u003d dict()"},{"line_number":691,"context_line":""},{"line_number":692,"context_line":"    def _create_network(self, networks_client\u003dNone,"},{"line_number":693,"context_line":"                        routers_client\u003dNone, tenant_id\u003dNone,"}],"source_content_type":"text/x-python","patch_set":1,"id":"bab6814e_79620218","line":690,"in_reply_to":"bab6814e_613416de","updated":"2016-05-24 20:06:43.000000000","message":"That works.  I was going to have the use counts saved on a per-instance (rather than per-class) basis but once per class works too.","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"8d42f9c3659a7b0100f625d057a5b51fecbd1288","unresolved":false,"context_lines":[{"line_number":801,"context_line":"        return subnet"},{"line_number":802,"context_line":""},{"line_number":803,"context_line":"    def _cleanup_subnet(self, subnet_id):"},{"line_number":804,"context_line":"        for (s, r) in self._router_id_use_counts.keys():"},{"line_number":805,"context_line":"            if subnet_id \u003d\u003d s:"},{"line_number":806,"context_line":"                self.routers_client.remove_router_interface(r,"},{"line_number":807,"context_line":"                                                        subnet_id\u003dsubnet_id)"}],"source_content_type":"text/x-python","patch_set":1,"id":"bab6814e_e1c926ae","line":804,"updated":"2016-05-24 14:56:15.000000000","message":"I\u0027m pretty sure keys() returns a list of keys, where is the tuple coming from? Did you mean to use items here instead?\n\nAlso check your python3 compat, it\u0027d be good to do this in a manner that works on python2 and python3. I don\u0027t remember the differences off the top of my head, but I know these dict methods changed in python3","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"bae16681e99d96751f553c10ebb149680c34b107","unresolved":false,"context_lines":[{"line_number":801,"context_line":"        return subnet"},{"line_number":802,"context_line":""},{"line_number":803,"context_line":"    def _cleanup_subnet(self, subnet_id):"},{"line_number":804,"context_line":"        for (s, r) in self._router_id_use_counts.keys():"},{"line_number":805,"context_line":"            if subnet_id \u003d\u003d s:"},{"line_number":806,"context_line":"                self.routers_client.remove_router_interface(r,"},{"line_number":807,"context_line":"                                                        subnet_id\u003dsubnet_id)"}],"source_content_type":"text/x-python","patch_set":1,"id":"bab6814e_f47b9727","line":804,"in_reply_to":"bab6814e_e1c926ae","updated":"2016-05-24 20:06:43.000000000","message":"Thanks for making me re-visit this!  We don\u0027t actually need to maintain a use count but rather just note when a specific (s,r) pair (s\u003dsubnet ID, r\u003drouter ID) has been associated.  I\u0027m changing this to be (hopefully) cleaner implementation.  Will now maintain a defaultdict with key\u003dsubnet ID and value\u003dset of router IDs.  Also adding more comments where we create the defaultdict to clarify what it is, and what it is used for.  All will be py3 compatible.","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"8d42f9c3659a7b0100f625d057a5b51fecbd1288","unresolved":false,"context_lines":[{"line_number":901,"context_line":"    def check_floating_ip_status(self, floating_ip, status):"},{"line_number":902,"context_line":"        \"\"\"Verifies floatingip reaches the given status"},{"line_number":903,"context_line":""},{"line_number":904,"context_line":"        :param floating_ip: floating_ips_client.create_floatingip"},{"line_number":905,"context_line":"        IP to check status"},{"line_number":906,"context_line":"        :param status: target status"},{"line_number":907,"context_line":"        :raises: AssertionError if status doesn\u0027t match"}],"source_content_type":"text/x-python","patch_set":1,"id":"bab6814e_61f1b6cd","line":904,"updated":"2016-05-24 14:56:15.000000000","message":"so normally the type goes between \u0027:param\u0027 and \u0027floating_ip:\u0027 space seperated. Something like::\n\n :param dict floating_ip: Floating ip dict to check status","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"bae16681e99d96751f553c10ebb149680c34b107","unresolved":false,"context_lines":[{"line_number":901,"context_line":"    def check_floating_ip_status(self, floating_ip, status):"},{"line_number":902,"context_line":"        \"\"\"Verifies floatingip reaches the given status"},{"line_number":903,"context_line":""},{"line_number":904,"context_line":"        :param floating_ip: floating_ips_client.create_floatingip"},{"line_number":905,"context_line":"        IP to check status"},{"line_number":906,"context_line":"        :param status: target status"},{"line_number":907,"context_line":"        :raises: AssertionError if status doesn\u0027t match"}],"source_content_type":"text/x-python","patch_set":1,"id":"bab6814e_8872ef0f","line":904,"in_reply_to":"bab6814e_61f1b6cd","updated":"2016-05-24 20:06:43.000000000","message":"Done","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"b84cb54edcba715874b5ba66270ef92f738af05c","unresolved":false,"context_lines":[{"line_number":883,"context_line":""},{"line_number":884,"context_line":"    def _associate_floating_ip(self, floating_ip, server):"},{"line_number":885,"context_line":"        port_id, _ \u003d self._get_server_port_id_and_ip4(server)"},{"line_number":886,"context_line":"        kwargs \u003d dict(port_id\u003dport_id)"},{"line_number":887,"context_line":"        floating_ip \u003d (self.floating_ips_client."},{"line_number":888,"context_line":"                       update_floatingip(floating_ip[\u0027id\u0027],"},{"line_number":889,"context_line":"                                         **kwargs)[\u0027floatingip\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_7eec7d29","line":886,"updated":"2016-05-25 12:31:14.000000000","message":"This looks weird. No need to use an indirection. I suggest\n\nfloating_ip \u003d self.floating_ips_client.update_floatingip(\n   floating_ip[\u0027id\u0027], port_id\u003dport_id)[\u0027floatingip\u0027]","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"9dca0523cda3f9bfce7e71b6c7b03e523470ef81","unresolved":false,"context_lines":[{"line_number":883,"context_line":""},{"line_number":884,"context_line":"    def _associate_floating_ip(self, floating_ip, server):"},{"line_number":885,"context_line":"        port_id, _ \u003d self._get_server_port_id_and_ip4(server)"},{"line_number":886,"context_line":"        kwargs \u003d dict(port_id\u003dport_id)"},{"line_number":887,"context_line":"        floating_ip \u003d (self.floating_ips_client."},{"line_number":888,"context_line":"                       update_floatingip(floating_ip[\u0027id\u0027],"},{"line_number":889,"context_line":"                                         **kwargs)[\u0027floatingip\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_7df3d20a","line":886,"in_reply_to":"bab6814e_7eec7d29","updated":"2016-05-25 16:29:25.000000000","message":"Done","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"b84cb54edcba715874b5ba66270ef92f738af05c","unresolved":false,"context_lines":[{"line_number":892,"context_line":""},{"line_number":893,"context_line":"    def _disassociate_floating_ip(self, floating_ip):"},{"line_number":894,"context_line":"        \"\"\":param floating_ip: floating_ips_client.create_floatingip\"\"\""},{"line_number":895,"context_line":"        kwargs \u003d dict(port_id\u003dNone)"},{"line_number":896,"context_line":"        floating_ip \u003d (self.floating_ips_client."},{"line_number":897,"context_line":"                       update_floatingip(floating_ip[\u0027id\u0027],"},{"line_number":898,"context_line":"                                         **kwargs)[\u0027floatingip\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_9ed04155","line":895,"updated":"2016-05-25 12:31:14.000000000","message":"same","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"9dca0523cda3f9bfce7e71b6c7b03e523470ef81","unresolved":false,"context_lines":[{"line_number":892,"context_line":""},{"line_number":893,"context_line":"    def _disassociate_floating_ip(self, floating_ip):"},{"line_number":894,"context_line":"        \"\"\":param floating_ip: floating_ips_client.create_floatingip\"\"\""},{"line_number":895,"context_line":"        kwargs \u003d dict(port_id\u003dNone)"},{"line_number":896,"context_line":"        floating_ip \u003d (self.floating_ips_client."},{"line_number":897,"context_line":"                       update_floatingip(floating_ip[\u0027id\u0027],"},{"line_number":898,"context_line":"                                         **kwargs)[\u0027floatingip\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_3dd02a53","line":895,"in_reply_to":"bab6814e_9ed04155","updated":"2016-05-25 16:29:25.000000000","message":"Done","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"b84cb54edcba715874b5ba66270ef92f738af05c","unresolved":false,"context_lines":[{"line_number":916,"context_line":"        tempest.test.call_until_true(refresh,"},{"line_number":917,"context_line":"                                     CONF.network.build_timeout,"},{"line_number":918,"context_line":"                                     CONF.network.build_interval)"},{"line_number":919,"context_line":"        floating_ip \u003d (self.floating_ips_client."},{"line_number":920,"context_line":"                       show_floatingip(floatingip_id)[\u0027floatingip\u0027])"},{"line_number":921,"context_line":"        self.assertEqual(status, floating_ip[\u0027status\u0027],"},{"line_number":922,"context_line":"                         message\u003d\"FloatingIP: {fp} is at status: {cst}. \""}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_be29c539","line":919,"updated":"2016-05-25 12:31:14.000000000","message":"No need for the extra ()\n\n  floating_ip \u003d self.floating_ips_client.show_floatingip(\n     floatingip_id)[\u0027floatingip\u0027]\n\nshould fit","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"9dca0523cda3f9bfce7e71b6c7b03e523470ef81","unresolved":false,"context_lines":[{"line_number":916,"context_line":"        tempest.test.call_until_true(refresh,"},{"line_number":917,"context_line":"                                     CONF.network.build_timeout,"},{"line_number":918,"context_line":"                                     CONF.network.build_interval)"},{"line_number":919,"context_line":"        floating_ip \u003d (self.floating_ips_client."},{"line_number":920,"context_line":"                       show_floatingip(floatingip_id)[\u0027floatingip\u0027])"},{"line_number":921,"context_line":"        self.assertEqual(status, floating_ip[\u0027status\u0027],"},{"line_number":922,"context_line":"                         message\u003d\"FloatingIP: {fp} is at status: {cst}. \""}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_9d6dd69b","line":919,"in_reply_to":"bab6814e_be29c539","updated":"2016-05-25 16:29:25.000000000","message":"Done","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"b84cb54edcba715874b5ba66270ef92f738af05c","unresolved":false,"context_lines":[{"line_number":1163,"context_line":"            return body[\u0027router\u0027]"},{"line_number":1164,"context_line":"        elif network_id:"},{"line_number":1165,"context_line":"            router \u003d self._create_router(client, tenant_id)"},{"line_number":1166,"context_line":"            kwargs \u003d {\u0027external_gateway_info\u0027:"},{"line_number":1167,"context_line":"                      dict(network_id\u003dnetwork_id)}"},{"line_number":1168,"context_line":"            router \u003d client.update_router(router[\u0027id\u0027],"},{"line_number":1169,"context_line":"                                          **kwargs)[\u0027router\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_deb489f3","line":1166,"updated":"2016-05-25 12:31:14.000000000","message":"same","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"9dca0523cda3f9bfce7e71b6c7b03e523470ef81","unresolved":false,"context_lines":[{"line_number":1163,"context_line":"            return body[\u0027router\u0027]"},{"line_number":1164,"context_line":"        elif network_id:"},{"line_number":1165,"context_line":"            router \u003d self._create_router(client, tenant_id)"},{"line_number":1166,"context_line":"            kwargs \u003d {\u0027external_gateway_info\u0027:"},{"line_number":1167,"context_line":"                      dict(network_id\u003dnetwork_id)}"},{"line_number":1168,"context_line":"            router \u003d client.update_router(router[\u0027id\u0027],"},{"line_number":1169,"context_line":"                                          **kwargs)[\u0027router\u0027]"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_fd0342b6","line":1166,"in_reply_to":"bab6814e_deb489f3","updated":"2016-05-25 16:29:25.000000000","message":"Done","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"b84cb54edcba715874b5ba66270ef92f738af05c","unresolved":false,"context_lines":[{"line_number":1191,"context_line":"        return router"},{"line_number":1192,"context_line":""},{"line_number":1193,"context_line":"    def _update_router_admin_state(self, router, admin_state_up):"},{"line_number":1194,"context_line":"        kwargs \u003d dict(admin_state_up\u003dadmin_state_up)"},{"line_number":1195,"context_line":"        router \u003d self.routers_client.update_router(router[\u0027id\u0027],"},{"line_number":1196,"context_line":"                                                   **kwargs)[\u0027router\u0027]"},{"line_number":1197,"context_line":"        self.assertEqual(admin_state_up, router[\u0027admin_state_up\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_3ec4b55d","line":1194,"updated":"2016-05-25 12:31:14.000000000","message":"same","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"9dca0523cda3f9bfce7e71b6c7b03e523470ef81","unresolved":false,"context_lines":[{"line_number":1191,"context_line":"        return router"},{"line_number":1192,"context_line":""},{"line_number":1193,"context_line":"    def _update_router_admin_state(self, router, admin_state_up):"},{"line_number":1194,"context_line":"        kwargs \u003d dict(admin_state_up\u003dadmin_state_up)"},{"line_number":1195,"context_line":"        router \u003d self.routers_client.update_router(router[\u0027id\u0027],"},{"line_number":1196,"context_line":"                                                   **kwargs)[\u0027router\u0027]"},{"line_number":1197,"context_line":"        self.assertEqual(admin_state_up, router[\u0027admin_state_up\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"bab6814e_3d882a22","line":1194,"in_reply_to":"bab6814e_3ec4b55d","updated":"2016-05-25 16:29:25.000000000","message":"this one doesn\u0027t fit (I assume you\u0027re talking about line 1195).\n\nupdated to:\n\n        router \u003d self.routers_client.update_router(\n            router[\u0027id\u0027], **kwargs)[\u0027router\u0027]","commit_id":"a5cc86fd4de3d9e49514b04fe093d7c086cb44b8"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"1c2b6745b7035355e2f7eec64b1013b14ba23925","unresolved":false,"context_lines":[{"line_number":686,"context_line":"        super(NetworkScenarioTest, cls).resource_setup()"},{"line_number":687,"context_line":"        cls.tenant_id \u003d cls.manager.identity_client.tenant_id"},{"line_number":688,"context_line":""},{"line_number":689,"context_line":"        # maintain a dict of associated subnets and routers.  The keys"},{"line_number":690,"context_line":"        # in this dict will be subnet IDs and the values in the dict"},{"line_number":691,"context_line":"        # will be a set of router IDs.  Each time we associate a router and"},{"line_number":692,"context_line":"        # subnet we will add to this dict.  This allows us to clean up"},{"line_number":693,"context_line":"        # correctly in the case where the same subnet is associated with"},{"line_number":694,"context_line":"        # multiple routers."},{"line_number":695,"context_line":"        cls.subnets_to_routers \u003d collections.defaultdict(set)"},{"line_number":696,"context_line":""},{"line_number":697,"context_line":"    def _create_network(self, networks_client\u003dNone,"}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_0a51fc0e","line":694,"range":{"start_line":689,"start_character":0,"end_line":694,"end_character":27},"updated":"2016-06-02 14:22:58.000000000","message":"I\u0027m not sure about this - we use the framework cleanup stack via addCleanup for the router and subnet creation, but not for the association. What is the reason for that? \n\nFor class level resources used by all tests we need a stack other cleanup actions other than the addCleanup, since the addCleanup stack is processed after every test. But we should not have such resources for scenario tests. \nWe do in some cases for API tests as we run so many of them and it makes sense to re-use expensive resources.","commit_id":"6b2986dfb99e4a45173a867983aa0711222c1a0b"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"1851f5e5795bd7d6baf182462e55bd8cb4d80ad2","unresolved":false,"context_lines":[{"line_number":686,"context_line":"        super(NetworkScenarioTest, cls).resource_setup()"},{"line_number":687,"context_line":"        cls.tenant_id \u003d cls.manager.identity_client.tenant_id"},{"line_number":688,"context_line":""},{"line_number":689,"context_line":"        # maintain a dict of associated subnets and routers.  The keys"},{"line_number":690,"context_line":"        # in this dict will be subnet IDs and the values in the dict"},{"line_number":691,"context_line":"        # will be a set of router IDs.  Each time we associate a router and"},{"line_number":692,"context_line":"        # subnet we will add to this dict.  This allows us to clean up"},{"line_number":693,"context_line":"        # correctly in the case where the same subnet is associated with"},{"line_number":694,"context_line":"        # multiple routers."},{"line_number":695,"context_line":"        cls.subnets_to_routers \u003d collections.defaultdict(set)"},{"line_number":696,"context_line":""},{"line_number":697,"context_line":"    def _create_network(self, networks_client\u003dNone,"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_66bde0b6","line":694,"range":{"start_line":689,"start_character":0,"end_line":694,"end_character":27},"in_reply_to":"7aa08908_8fcd8ab9","updated":"2016-06-07 21:02:14.000000000","message":"Right, what I was suggesting is to simply stack the required removal of subnets from router via addCleanup - that should be enough to ensure that by the time we get to the router deletion all subnets have been disconnected.","commit_id":"6b2986dfb99e4a45173a867983aa0711222c1a0b"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"5f00a5543efee458be42c0eb3ce192fd146beebe","unresolved":false,"context_lines":[{"line_number":686,"context_line":"        super(NetworkScenarioTest, cls).resource_setup()"},{"line_number":687,"context_line":"        cls.tenant_id \u003d cls.manager.identity_client.tenant_id"},{"line_number":688,"context_line":""},{"line_number":689,"context_line":"        # maintain a dict of associated subnets and routers.  The keys"},{"line_number":690,"context_line":"        # in this dict will be subnet IDs and the values in the dict"},{"line_number":691,"context_line":"        # will be a set of router IDs.  Each time we associate a router and"},{"line_number":692,"context_line":"        # subnet we will add to this dict.  This allows us to clean up"},{"line_number":693,"context_line":"        # correctly in the case where the same subnet is associated with"},{"line_number":694,"context_line":"        # multiple routers."},{"line_number":695,"context_line":"        cls.subnets_to_routers \u003d collections.defaultdict(set)"},{"line_number":696,"context_line":""},{"line_number":697,"context_line":"    def _create_network(self, networks_client\u003dNone,"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_8fcd8ab9","line":694,"range":{"start_line":689,"start_character":0,"end_line":694,"end_character":27},"in_reply_to":"9abb7d3a_0a51fc0e","updated":"2016-06-07 18:11:16.000000000","message":"I added this because the old DeletableSubnet wrapper object was the one who maintained the router/subnet relationship thru a list of routers.  When you deleted a subnet it would remove it from its associated routers. This just moves that behavior from the old code into manager.","commit_id":"6b2986dfb99e4a45173a867983aa0711222c1a0b"},{"author":{"_account_id":1921,"name":"Andrea Frittoli","email":"andrea.frittoli@gmail.com","username":"andrea-frittoli"},"change_message_id":"1c2b6745b7035355e2f7eec64b1013b14ba23925","unresolved":false,"context_lines":[{"line_number":812,"context_line":"                        subnets_client\u003dNone):"},{"line_number":813,"context_line":"        # Remove the subnet interface from each router for which we"},{"line_number":814,"context_line":"        # have previously added this subnet."},{"line_number":815,"context_line":"        if not routers_client:"},{"line_number":816,"context_line":"            routers_client \u003d self.routers_client"},{"line_number":817,"context_line":"        if not subnets_client:"},{"line_number":818,"context_line":"            subnets_client \u003d self.subnets_client"},{"line_number":819,"context_line":""},{"line_number":820,"context_line":"        while self.subnets_to_routers[subnet_id]:"},{"line_number":821,"context_line":"            router_id \u003d self.subnets_to_routers[subnet_id].pop()"}],"source_content_type":"text/x-python","patch_set":11,"id":"9abb7d3a_b0e66442","line":818,"range":{"start_line":815,"start_character":0,"end_line":818,"end_character":48},"updated":"2016-06-02 14:22:58.000000000","message":"NIT: I would discourage doing this. This method is invoked 3 times overall, and two of them clients are passed. We could easily make the two clients mandatory and code readability would benefit from it, because it makes it clearer which clients are used to cleanup and thus which credentials.\nI would hope in future to move this helpers out of scenario specific classes, they could be easily shared with API tests as well - for that not depending on any class state (self) is essential.","commit_id":"6b2986dfb99e4a45173a867983aa0711222c1a0b"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"5f00a5543efee458be42c0eb3ce192fd146beebe","unresolved":false,"context_lines":[{"line_number":812,"context_line":"                        subnets_client\u003dNone):"},{"line_number":813,"context_line":"        # Remove the subnet interface from each router for which we"},{"line_number":814,"context_line":"        # have previously added this subnet."},{"line_number":815,"context_line":"        if not routers_client:"},{"line_number":816,"context_line":"            routers_client \u003d self.routers_client"},{"line_number":817,"context_line":"        if not subnets_client:"},{"line_number":818,"context_line":"            subnets_client \u003d self.subnets_client"},{"line_number":819,"context_line":""},{"line_number":820,"context_line":"        while self.subnets_to_routers[subnet_id]:"},{"line_number":821,"context_line":"            router_id \u003d self.subnets_to_routers[subnet_id].pop()"}],"source_content_type":"text/x-python","patch_set":11,"id":"7aa08908_0f519ad8","line":818,"range":{"start_line":815,"start_character":0,"end_line":818,"end_character":48},"in_reply_to":"9abb7d3a_b0e66442","updated":"2016-06-07 18:11:16.000000000","message":"I will gladly update to make the clients required parameters.","commit_id":"6b2986dfb99e4a45173a867983aa0711222c1a0b"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"c713493a7843d2be9f186475aa2e130730e07ce0","unresolved":false,"context_lines":[{"line_number":806,"context_line":""},{"line_number":807,"context_line":"        return subnet"},{"line_number":808,"context_line":""},{"line_number":809,"context_line":"    def _remove_subnet_router_assoc(self, subnet_id, router_id,"},{"line_number":810,"context_line":"                                    routers_client):"},{"line_number":811,"context_line":"        routers_client.remove_router_interface(router_id, subnet_id\u003dsubnet_id)"},{"line_number":812,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"7aa08908_eed14d58","line":809,"updated":"2016-06-14 21:44:18.000000000","message":"Why do you create an alias of the routers_client.remove_router_interface function ?\n\nAs a reviewer I know the function routers_client.remove_router_interface, it\u0027s used everywhere in Tempest code base. Now here you introduce a new function called _remove_subnet_router_assoc that does the same thing with a different name. My head is already full of method names, I don\"t want to learn a new one...","commit_id":"fc1752f7d55e75d6432dae2eee7dc63760642dd2"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"4b98232571ebdd889c4de3b92352f3349984370d","unresolved":false,"context_lines":[{"line_number":806,"context_line":""},{"line_number":807,"context_line":"        return subnet"},{"line_number":808,"context_line":""},{"line_number":809,"context_line":"    def _remove_subnet_router_assoc(self, subnet_id, router_id,"},{"line_number":810,"context_line":"                                    routers_client):"},{"line_number":811,"context_line":"        routers_client.remove_router_interface(router_id, subnet_id\u003dsubnet_id)"},{"line_number":812,"context_line":""}],"source_content_type":"text/x-python","patch_set":19,"id":"7aa08908_4ecea15a","line":809,"in_reply_to":"7aa08908_eed14d58","updated":"2016-06-14 22:12:38.000000000","message":"I completely agree.  Previously this function had more code.  Cleaning it up in next CR.","commit_id":"fc1752f7d55e75d6432dae2eee7dc63760642dd2"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"c713493a7843d2be9f186475aa2e130730e07ce0","unresolved":false,"context_lines":[{"line_number":810,"context_line":"                                    routers_client):"},{"line_number":811,"context_line":"        routers_client.remove_router_interface(router_id, subnet_id\u003dsubnet_id)"},{"line_number":812,"context_line":""},{"line_number":813,"context_line":"    def _delete_subnet(self, subnet_id, subnets_client):"},{"line_number":814,"context_line":"        subnets_client.delete_subnet(subnet_id)"},{"line_number":815,"context_line":""},{"line_number":816,"context_line":"    def _create_port(self, network_id, client\u003dNone, namestart\u003d\u0027port-quotatest\u0027,"}],"source_content_type":"text/x-python","patch_set":19,"id":"7aa08908_ae53c5e0","line":813,"updated":"2016-06-14 21:44:18.000000000","message":"Same here. There should be one function to delete a subnet, and that function is subnets_client.delete_subnet.\n\nIf we go that road, the next 3 patches will introduce the following functions: my_delete_subnet, safe_delete_subnet, delete_subnet_of_a_network...","commit_id":"fc1752f7d55e75d6432dae2eee7dc63760642dd2"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"4b98232571ebdd889c4de3b92352f3349984370d","unresolved":false,"context_lines":[{"line_number":810,"context_line":"                                    routers_client):"},{"line_number":811,"context_line":"        routers_client.remove_router_interface(router_id, subnet_id\u003dsubnet_id)"},{"line_number":812,"context_line":""},{"line_number":813,"context_line":"    def _delete_subnet(self, subnet_id, subnets_client):"},{"line_number":814,"context_line":"        subnets_client.delete_subnet(subnet_id)"},{"line_number":815,"context_line":""},{"line_number":816,"context_line":"    def _create_port(self, network_id, client\u003dNone, namestart\u003d\u0027port-quotatest\u0027,"}],"source_content_type":"text/x-python","patch_set":19,"id":"7aa08908_aed90524","line":813,"in_reply_to":"7aa08908_ae53c5e0","updated":"2016-06-14 22:12:38.000000000","message":"ditto above.","commit_id":"fc1752f7d55e75d6432dae2eee7dc63760642dd2"}],"tempest/scenario/test_network_basic_ops.py":[{"author":{"_account_id":5196,"name":"Matthew Treinish","email":"mtreinish@kortar.org","username":"treinish"},"change_message_id":"8d42f9c3659a7b0100f625d057a5b51fecbd1288","unresolved":false,"context_lines":[{"line_number":285,"context_line":"        num, new_nic \u003d self.diff_list[0]"},{"line_number":286,"context_line":"        ssh_client.assign_static_ip(nic\u003dnew_nic,"},{"line_number":287,"context_line":"                                    addr\u003dnew_port[\u0027fixed_ips\u0027]"},{"line_number":288,"context_line":"                                    [0][\u0027ip_address\u0027])"},{"line_number":289,"context_line":"        ssh_client.set_nic_state(nic\u003dnew_nic)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"    def _get_server_nics(self, ssh_client):"}],"source_content_type":"text/x-python","patch_set":1,"id":"bab6814e_9e94f7e8","line":288,"updated":"2016-05-24 14:56:15.000000000","message":"nit: just my personal preference here, but I normally prefer to keep all the list and dict fields to be on the same row as the variable being accessed. It\u0027s a bit weird to see [0][\u0027ip_address\u0027] by itself","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"bae16681e99d96751f553c10ebb149680c34b107","unresolved":false,"context_lines":[{"line_number":285,"context_line":"        num, new_nic \u003d self.diff_list[0]"},{"line_number":286,"context_line":"        ssh_client.assign_static_ip(nic\u003dnew_nic,"},{"line_number":287,"context_line":"                                    addr\u003dnew_port[\u0027fixed_ips\u0027]"},{"line_number":288,"context_line":"                                    [0][\u0027ip_address\u0027])"},{"line_number":289,"context_line":"        ssh_client.set_nic_state(nic\u003dnew_nic)"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"    def _get_server_nics(self, ssh_client):"}],"source_content_type":"text/x-python","patch_set":1,"id":"bab6814e_4d582357","line":288,"in_reply_to":"bab6814e_9e94f7e8","updated":"2016-05-24 20:06:43.000000000","message":"Done","commit_id":"8637a5da2e8040a17eb57dacc54062a62b9598fa"},{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"034bf23c4074b172e951ee504b8fac0b4d4c9999","unresolved":false,"context_lines":[{"line_number":574,"context_line":"                                 act_serv\u003dservers,"},{"line_number":575,"context_line":"                                 trgt_serv\u003ddns_servers))"},{"line_number":576,"context_line":""},{"line_number":577,"context_line":"        self.subnet \u003d (self.subnets_client."},{"line_number":578,"context_line":"                       update_subnet"},{"line_number":579,"context_line":"                       (self.subnet[\u0027id\u0027],"},{"line_number":580,"context_line":"                        dns_nameservers\u003d[alt_dns_server]))[\u0027subnet\u0027]"}],"source_content_type":"text/x-python","patch_set":9,"id":"9abb7d3a_a3ec1690","line":577,"updated":"2016-05-30 15:16:02.000000000","message":"This looks weird. We can format the code in a better way imo.","commit_id":"a803e6f23d7a9b4b925cc5248b294817f7614e73"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"4b98232571ebdd889c4de3b92352f3349984370d","unresolved":false,"context_lines":[{"line_number":574,"context_line":"                                 act_serv\u003dservers,"},{"line_number":575,"context_line":"                                 trgt_serv\u003ddns_servers))"},{"line_number":576,"context_line":""},{"line_number":577,"context_line":"        self.subnet \u003d (self.subnets_client.update_subnet("},{"line_number":578,"context_line":"            self.subnet[\u0027id\u0027], dns_nameservers\u003d[alt_dns_server]))[\u0027subnet\u0027]"},{"line_number":579,"context_line":""},{"line_number":580,"context_line":"        # asserts that Neutron DB has updated the nameservers"}],"source_content_type":"text/x-python","patch_set":19,"id":"7aa08908_ae046517","line":577,"updated":"2016-06-14 22:12:38.000000000","message":"removed these extra parens.","commit_id":"fc1752f7d55e75d6432dae2eee7dc63760642dd2"},{"author":{"_account_id":9234,"name":"Steve Heyman","email":"steve@heyman.com","username":"hockeynut"},"change_message_id":"4b98232571ebdd889c4de3b92352f3349984370d","unresolved":false,"context_lines":[{"line_number":703,"context_line":""},{"line_number":704,"context_line":"        # NOTE(kevinbenton): we have to use the admin credentials to check"},{"line_number":705,"context_line":"        # for the distributed flag because self.router only has a project view."},{"line_number":706,"context_line":"        admin \u003d (self.admin_manager."},{"line_number":707,"context_line":"                 routers_client.show_router(self.router[\u0027id\u0027]))"},{"line_number":708,"context_line":"        if admin[\u0027router\u0027].get(\u0027distributed\u0027, False):"},{"line_number":709,"context_line":"            msg \u003d \"Rescheduling test does not apply to distributed routers.\""}],"source_content_type":"text/x-python","patch_set":19,"id":"7aa08908_f1001003","line":706,"updated":"2016-06-14 22:12:38.000000000","message":"removed these extra parens","commit_id":"fc1752f7d55e75d6432dae2eee7dc63760642dd2"}]}
