allocate_dynamic_segment() returns different segment dicts if segment exists

Bug #1926428 reported by Sebastian Lohff
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
neutron
New
Low
Unassigned

Bug Description

neutron.plugins.ml2.managers.TypeManager.allocate_dynamic_segment() returns a different segment dict describing the segment, depending upon if the segment exists or not. If the segment already exists neutron returns segments_db.get_dynamic_segment() which generated the dict via neutron.db.segments_db._make_segment_dict(). If it does not exist it is created and a dict is returned generated by a TypeDriver. In the testcase below this is done via VlanTypeDriver.allocate_tenant_segment(), which does not return a network_id but a MTU instead.

class TestMultiSegmentNetworks(Ml2PluginV2TestCase):
   ...
    def test_allocate_dynamic_segment_twice(self):
        data = {'network': {'name': 'net1',
                            'tenant_id': 'tenant_one'}}
        network_req = self.new_create_request('networks', data)
        network = self.deserialize(self.fmt,
                                   network_req.get_response(self.api))
        segment = {driver_api.NETWORK_TYPE: 'vlan',
                   driver_api.PHYSICAL_NETWORK: 'physnet1'}
        network_id = network['network']['id']

        seg1 = self.driver.type_manager.allocate_dynamic_segment(
            self.context, network_id, segment)
        seg2 = self.driver.type_manager.allocate_dynamic_segment(
            self.context, network_id, segment)
        self.assertEqual(seg1, seg2)

Which results in this output:

 testtools.matchers._impl.MismatchError: !=:
reference = {'id': 'a5c92a94-e182-47fb-ae8f-fe9d75ef10ce',
 'mtu': 1500,
 'network_type': 'vlan',
 'physical_network': 'physnet1',
 'segmentation_id': 83}
actual = {'id': 'a5c92a94-e182-47fb-ae8f-fe9d75ef10ce',
 'network_id': '9ac10cc3-d3d0-46f7-9f6b-31767fadacec',
 'network_type': 'vlan',
 'physical_network': 'physnet1',
 'segmentation_id': 83}

This was tested on current neutron master (98c934ef6a8041bbd7b99ac49f53986798e8ef81).

The easiest way to fix this would probably be to just fetch the segment again from the db if it was created. Then we also would not be at the mercy of whatever the typedriver returns on create, though this would result in an extra query on segment create. The other option I see would be to make _make_segment_dict() public and let each TypeDriver use this, though this would not work for externally written TypeDrivers.

tags: added: low-hanging-fruit
tags: added: ml2
Changed in neutron:
importance: Undecided → Low
Revision history for this message
Rodolfo Alonso (rodolfo-alonso-hernandez) wrote :

Hello Sebastian:

How are you calling this method? Although this method belongs to the PortContext API, so far there is no active project using it [1]. Can you provide this info?

Regards.

[1]https://codesearch.openstack.org/?q=allocate_dynamic_segment&i=nope&files=&excludeFiles=&repos=

Revision history for this message
Rodolfo Alonso (rodolfo-alonso-hernandez) wrote :

Actually checking the result you provided, this "TypeDriver.reserve_provider_segment" result is none of the in-tree ones because none of them return the ID.

A segment is defined by the following tuple: network type, physical network and segmentation ID. Any other attribute, ID or MTU, is additional information that does not characterize the segment itself.

Although we should provide a common result, this is not enforced by the API. I suggest you to change you test check.

Regards.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.