)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"92ea01cb817a5a840917f89fc28b48e4ee302b90","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Ensure tempest tests don\u0027t assume IP address allocation strategy"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"With the advent of pluggable IPAM in Neutron, it is not safe to"},{"line_number":10,"context_line":"assume any particular algorithm is used to allocate IP addresses."},{"line_number":11,"context_line":"This change ensures the fixed IP sent to Neutron when we need a"},{"line_number":12,"context_line":"specific fixed IP doesn\u0027t conflict as it is unsafe to simply take"},{"line_number":13,"context_line":"the numerically highest IP address and add 1 to it. This change"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"dab17558_15f90281","line":10,"updated":"2016-05-06 22:40:31.000000000","message":"I\u0027d argue that it was never safe to assume the IP allocation strategy ever, as that\u0027s not part of the API contract. I must have said this once or twice somewhere already. Right, Carl? :)","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"a9789121bf76a053ee5c398e0e3654ac5cb68965","unresolved":false,"context_lines":[{"line_number":7,"context_line":"Ensure tempest tests don\u0027t assume IP address allocation strategy"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"With the advent of pluggable IPAM in Neutron, it is not safe to"},{"line_number":10,"context_line":"assume any particular algorithm is used to allocate IP addresses."},{"line_number":11,"context_line":"This change ensures the fixed IP sent to Neutron when we need a"},{"line_number":12,"context_line":"specific fixed IP doesn\u0027t conflict as it is unsafe to simply take"},{"line_number":13,"context_line":"the numerically highest IP address and add 1 to it. This change"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"dab17558_f5227eb8","line":10,"in_reply_to":"dab17558_15f90281","updated":"2016-05-06 22:52:18.000000000","message":"You\u0027d be surprised how many docstrings I have found that claim this is part of the contract :(","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"92ea01cb817a5a840917f89fc28b48e4ee302b90","unresolved":false,"context_lines":[{"line_number":10,"context_line":"assume any particular algorithm is used to allocate IP addresses."},{"line_number":11,"context_line":"This change ensures the fixed IP sent to Neutron when we need a"},{"line_number":12,"context_line":"specific fixed IP doesn\u0027t conflict as it is unsafe to simply take"},{"line_number":13,"context_line":"the numerically highest IP address and add 1 to it. This change"},{"line_number":14,"context_line":"introduces a helper method that finds an IP address not in use,"},{"line_number":15,"context_line":"making it so we can safely ask for that specific IP address."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"dab17558_75304e57","line":13,"updated":"2016-05-06 22:40:31.000000000","message":"Totally unsafe, I am surprised this hasn\u0027t bitten us already.","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"a9789121bf76a053ee5c398e0e3654ac5cb68965","unresolved":false,"context_lines":[{"line_number":10,"context_line":"assume any particular algorithm is used to allocate IP addresses."},{"line_number":11,"context_line":"This change ensures the fixed IP sent to Neutron when we need a"},{"line_number":12,"context_line":"specific fixed IP doesn\u0027t conflict as it is unsafe to simply take"},{"line_number":13,"context_line":"the numerically highest IP address and add 1 to it. This change"},{"line_number":14,"context_line":"introduces a helper method that finds an IP address not in use,"},{"line_number":15,"context_line":"making it so we can safely ask for that specific IP address."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":4,"id":"dab17558_352d26a8","line":13,"in_reply_to":"dab17558_75304e57","updated":"2016-05-06 22:52:18.000000000","message":"+1","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"}],"tempest/api/compute/base.py":[{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"762412f722d1a03afb793d881cfa2b20b9276eed","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                cls.server_id \u003d None"},{"line_number":174,"context_line":"                raise"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def _generate_unique_ip_addresses(self, network_id, subnet_id, count):"},{"line_number":177,"context_line":"        ports \u003d self.ports_client.list_ports(network_id\u003dnetwork_id)[\u0027ports\u0027]"},{"line_number":178,"context_line":"        subnet \u003d self.subnets_client.show_subnet(subnet_id)"},{"line_number":179,"context_line":"        ip_net \u003d netaddr.IPNetwork(subnet[\u0027subnet\u0027][\u0027cidr\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a122d0e_31f31375","line":176,"updated":"2016-05-05 04:01:01.000000000","message":"You\u0027ll find the exact same method in tempest/api/network/test_floating_ips.py. I\u0027d like to find a common place for this to live.","commit_id":"6184e60d5d9becb3527db15bd99c5ea64ef0ad5d"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"ab5aa15b6154ebbab045ca22ee529bf387f785a2","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                cls.server_id \u003d None"},{"line_number":174,"context_line":"                raise"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def _generate_unique_ip_addresses(self, network_id, subnet_id, count):"},{"line_number":177,"context_line":"        ports \u003d self.ports_client.list_ports(network_id\u003dnetwork_id)[\u0027ports\u0027]"},{"line_number":178,"context_line":"        subnet \u003d self.subnets_client.show_subnet(subnet_id)"},{"line_number":179,"context_line":"        ip_net \u003d netaddr.IPNetwork(subnet[\u0027subnet\u0027][\u0027cidr\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"dab17558_640422c0","line":176,"in_reply_to":"1a122d0e_2810a1ff","updated":"2016-05-06 21:04:58.000000000","message":"Done","commit_id":"6184e60d5d9becb3527db15bd99c5ea64ef0ad5d"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"a61a085810c24228f9083d9d080f87b2c78e6871","unresolved":false,"context_lines":[{"line_number":173,"context_line":"                cls.server_id \u003d None"},{"line_number":174,"context_line":"                raise"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def _generate_unique_ip_addresses(self, network_id, subnet_id, count):"},{"line_number":177,"context_line":"        ports \u003d self.ports_client.list_ports(network_id\u003dnetwork_id)[\u0027ports\u0027]"},{"line_number":178,"context_line":"        subnet \u003d self.subnets_client.show_subnet(subnet_id)"},{"line_number":179,"context_line":"        ip_net \u003d netaddr.IPNetwork(subnet[\u0027subnet\u0027][\u0027cidr\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a122d0e_2810a1ff","line":176,"in_reply_to":"1a122d0e_31f31375","updated":"2016-05-05 19:23:26.000000000","message":"How about a new file under common/utils?","commit_id":"6184e60d5d9becb3527db15bd99c5ea64ef0ad5d"},{"author":{"_account_id":7448,"name":"Carl Baldwin","email":"carl@ecbaldwin.net","username":"carl-baldwin"},"change_message_id":"a61a085810c24228f9083d9d080f87b2c78e6871","unresolved":false,"context_lines":[{"line_number":185,"context_line":"                alloc_set.add(fixed_ip[\u0027ip_address\u0027])"},{"line_number":186,"context_line":""},{"line_number":187,"context_line":"        # pull IP addresses that are not in alloc_set"},{"line_number":188,"context_line":"        ip_list \u003d []"},{"line_number":189,"context_line":"        for ip in ip_net.iter_hosts():"},{"line_number":190,"context_line":"            if len(ip_list) \u003e\u003d count:"},{"line_number":191,"context_line":"                break"},{"line_number":192,"context_line":"            if ip not in alloc_set:"},{"line_number":193,"context_line":"                ip_list.append(str(ip))"},{"line_number":194,"context_line":""},{"line_number":195,"context_line":"        if len(ip_list) !\u003d count:"},{"line_number":196,"context_line":"            msg \u003d \"Insufficient IP addresses available\""}],"source_content_type":"text/x-python","patch_set":2,"id":"1a122d0e_288421d1","line":193,"range":{"start_line":188,"start_character":8,"end_line":193,"end_character":39},"updated":"2016-05-05 19:23:26.000000000","message":"Just a suggestion to use set arithmetic.\n\n  subnet_set \u003d netaddr.IPSet(ip_net.iter_hosts())\n  ip_list \u003d [str(ip) for ip in itertools.islice(subnet_set - alloc_set, count))]","commit_id":"6184e60d5d9becb3527db15bd99c5ea64ef0ad5d"}],"tempest/api/network/base.py":[{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"762412f722d1a03afb793d881cfa2b20b9276eed","unresolved":false,"context_lines":[{"line_number":152,"context_line":"        except lib_exc.NotFound:"},{"line_number":153,"context_line":"            pass"},{"line_number":154,"context_line":""},{"line_number":155,"context_line":"    def _generate_unique_ip_addresses(self, network_id, subnet_id, count):"},{"line_number":156,"context_line":"        ports \u003d self.ports_client.list_ports(network_id\u003dnetwork_id)[\u0027ports\u0027]"},{"line_number":157,"context_line":"        subnet \u003d self.subnets_client.show_subnet(subnet_id)"},{"line_number":158,"context_line":"        ip_net \u003d netaddr.IPNetwork(subnet[\u0027subnet\u0027][\u0027cidr\u0027])"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a122d0e_d1029f3d","line":155,"updated":"2016-05-05 04:01:01.000000000","message":"You\u0027ll find the exact same method in tempest/api/compute/base.py. I\u0027d like to find a common place for this to live.","commit_id":"6184e60d5d9becb3527db15bd99c5ea64ef0ad5d"}],"tempest/api/network/test_floating_ips.py":[{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"1cb5621e76457d073ebd09cbd20770017d10307c","unresolved":false,"context_lines":[{"line_number":195,"context_line":"            self.ports_client,"},{"line_number":196,"context_line":"            self.subnets_client,"},{"line_number":197,"context_line":"            self.subnet[\u0027network_id\u0027],"},{"line_number":198,"context_line":"            self.subnet[\u0027id\u0027],"},{"line_number":199,"context_line":"            2)"},{"line_number":200,"context_line":"        fixed_ips \u003d [{\u0027ip_address\u0027: list_ips[0]}, {\u0027ip_address\u0027: list_ips[1]}]"},{"line_number":201,"context_line":"        # Create port"}],"source_content_type":"text/x-python","patch_set":4,"id":"dab17558_900500c4","line":198,"updated":"2016-05-06 23:01:02.000000000","message":"Now that I think about, I wonder if this test should create its own subnet that is not shared with other tests so we can eliminate concurrency issues when trying to find unique IP addresses for this test to use.","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"}],"tempest/common/utils/net_utils.py":[{"author":{"_account_id":7350,"name":"Jordan Pittier","email":"jordan.pittier@gmail.com","username":"JordanP"},"change_message_id":"20c80cb68f2f10a6bcc40e9c2d41f0bad880a09e","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from tempest.lib import exceptions as lib_exc"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def generate_unique_ip_addresses(ports_client, subnets_client,"},{"line_number":22,"context_line":"                                 network_id, subnet_id, count):"},{"line_number":23,"context_line":"    ports \u003d ports_client.list_ports(network_id\u003dnetwork_id)[\u0027ports\u0027]"},{"line_number":24,"context_line":"    subnet \u003d subnets_client.show_subnet(subnet_id)"}],"source_content_type":"text/x-python","patch_set":4,"id":"dab17558_6397d390","line":21,"updated":"2016-05-09 10:26:40.000000000","message":"Could we rename this to get_unused_ip_addresses ? I mean unique is a bit vague, and has several meanings. And we don\"t really \"generate\" IPs.","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"f5d3fc1fe09d615d2a30179bc5f49840d01adbba","unresolved":false,"context_lines":[{"line_number":18,"context_line":"from tempest.lib import exceptions as lib_exc"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def generate_unique_ip_addresses(ports_client, subnets_client,"},{"line_number":22,"context_line":"                                 network_id, subnet_id, count):"},{"line_number":23,"context_line":"    ports \u003d ports_client.list_ports(network_id\u003dnetwork_id)[\u0027ports\u0027]"},{"line_number":24,"context_line":"    subnet \u003d subnets_client.show_subnet(subnet_id)"}],"source_content_type":"text/x-python","patch_set":4,"id":"dab17558_d43c6ee4","line":21,"in_reply_to":"dab17558_6397d390","updated":"2016-05-09 15:26:36.000000000","message":"Sure, \"unused\" is more precise. Done.","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"92ea01cb817a5a840917f89fc28b48e4ee302b90","unresolved":false,"context_lines":[{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def generate_unique_ip_addresses(ports_client, subnets_client,"},{"line_number":22,"context_line":"                                 network_id, subnet_id, count):"},{"line_number":23,"context_line":"    ports \u003d ports_client.list_ports(network_id\u003dnetwork_id)[\u0027ports\u0027]"},{"line_number":24,"context_line":"    subnet \u003d subnets_client.show_subnet(subnet_id)"},{"line_number":25,"context_line":"    ip_net \u003d netaddr.IPNetwork(subnet[\u0027subnet\u0027][\u0027cidr\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"dab17558_d5413a0d","line":22,"updated":"2016-05-06 22:40:31.000000000","message":"can you add a docstring?","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"a9789121bf76a053ee5c398e0e3654ac5cb68965","unresolved":false,"context_lines":[{"line_number":19,"context_line":""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"def generate_unique_ip_addresses(ports_client, subnets_client,"},{"line_number":22,"context_line":"                                 network_id, subnet_id, count):"},{"line_number":23,"context_line":"    ports \u003d ports_client.list_ports(network_id\u003dnetwork_id)[\u0027ports\u0027]"},{"line_number":24,"context_line":"    subnet \u003d subnets_client.show_subnet(subnet_id)"},{"line_number":25,"context_line":"    ip_net \u003d netaddr.IPNetwork(subnet[\u0027subnet\u0027][\u0027cidr\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"dab17558_d512da61","line":22,"in_reply_to":"dab17558_d5413a0d","updated":"2016-05-06 22:52:18.000000000","message":"Will do","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"},{"author":{"_account_id":748,"name":"Armando Migliaccio","email":"armamig@gmail.com","username":"armando-migliaccio"},"change_message_id":"92ea01cb817a5a840917f89fc28b48e4ee302b90","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    # prune out any addresses already allocated to existing ports"},{"line_number":30,"context_line":"    for port in ports:"},{"line_number":31,"context_line":"        for fixed_ip in port.get(\u0027fixed_ips\u0027):"},{"line_number":32,"context_line":"            alloc_set.add(fixed_ip[\u0027ip_address\u0027])"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    av_set \u003d subnet_set - alloc_set"},{"line_number":35,"context_line":"    ip_list \u003d [str(ip) for ip in itertools.islice(av_set, count)]"}],"source_content_type":"text/x-python","patch_set":4,"id":"dab17558_955e92e7","line":32,"updated":"2016-05-06 22:40:31.000000000","message":"Should this method assume that ports may have indeed disappeared throughout the iteration?","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"},{"author":{"_account_id":4187,"name":"Ryan Tidwell","email":"rtidwell@suse.com","username":"ryan-tidwell"},"change_message_id":"a9789121bf76a053ee5c398e0e3654ac5cb68965","unresolved":false,"context_lines":[{"line_number":29,"context_line":"    # prune out any addresses already allocated to existing ports"},{"line_number":30,"context_line":"    for port in ports:"},{"line_number":31,"context_line":"        for fixed_ip in port.get(\u0027fixed_ips\u0027):"},{"line_number":32,"context_line":"            alloc_set.add(fixed_ip[\u0027ip_address\u0027])"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    av_set \u003d subnet_set - alloc_set"},{"line_number":35,"context_line":"    ip_list \u003d [str(ip) for ip in itertools.islice(av_set, count)]"}],"source_content_type":"text/x-python","patch_set":4,"id":"dab17558_95605237","line":32,"in_reply_to":"dab17558_955e92e7","updated":"2016-05-06 22:52:18.000000000","message":"Oh man, you just had to bring up concurrency :) Having one of the ports we queried here pulled out from underneath us doesn\u0027t really have any adverse effect, it just means we consider the IP address it had as being allocated.\n\nI think where we actually get into trouble is when a port is created and takes an IP address out from underneath this method. As long as your test owns the subnet it\u0027s passing in then this is actually pretty isolated. If other tests are operating on the same subnet this is definitely not safe.","commit_id":"aa063f3bf4cd6ba89d605b67aa4c2885a3bac6be"}]}
