← Back to team overview

yahoo-eng-team team mailing list archive

[Bug 1926428] [NEW] allocate_dynamic_segment() returns different segment dicts if segment exists

 

Public bug reported:

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.

** Affects: neutron
     Importance: Undecided
         Status: New

-- 
You received this bug notification because you are a member of Yahoo!
Engineering Team, which is subscribed to neutron.
https://bugs.launchpad.net/bugs/1926428

Title:
  allocate_dynamic_segment() returns different segment dicts if segment
  exists

Status in neutron:
  New

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.

To manage notifications about this bug go to:
https://bugs.launchpad.net/neutron/+bug/1926428/+subscriptions