summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2012-10-29 01:59:25 +0000
committerGerrit Code Review <review@openstack.org>2012-10-29 01:59:25 +0000
commit316d8b73e7b5eac4de0ef6c820595f47af6fb615 (patch)
treef3ad43c4ccad215bcb3b76b1c15ebc2594fef6d5
parente8af7fb5d725287362323fe451593665cb5ce593 (diff)
parent91fb1ce5c8b8c11fb6e35d8774b7df48da0786b3 (diff)
Merge "Fix nova-network MAC collision logic"
-rw-r--r--nova/db/sqlalchemy/api.py2
-rw-r--r--nova/tests/network/test_manager.py33
2 files changed, 34 insertions, 1 deletions
diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py
index da8c559c6..8f4640ea9 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1272,7 +1272,7 @@ def virtual_interface_create(context, values):
vif_ref = models.VirtualInterface()
vif_ref.update(values)
vif_ref.save()
- except IntegrityError:
+ except exception.DBError:
raise exception.VirtualInterfaceCreateException()
return vif_ref
diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py
index 988844883..f5ac26e0a 100644
--- a/nova/tests/network/test_manager.py
+++ b/nova/tests/network/test_manager.py
@@ -21,6 +21,7 @@ import tempfile
from nova import context
from nova import db
+from nova.db.sqlalchemy import models
from nova import exception
from nova.network import linux_net
from nova.network import manager as network_manager
@@ -1843,6 +1844,38 @@ class FloatingIPTestCase(test.TestCase):
self.network.delete_dns_domain(context_admin, domain1)
self.network.delete_dns_domain(context_admin, domain2)
+ def test_mac_conflicts(self):
+ """Make sure MAC collisions are retried"""
+ self.flags(create_unique_mac_address_attempts=3)
+ ctxt = context.RequestContext('testuser', 'testproject', is_admin=True)
+ macs = ['bb:bb:bb:bb:bb:bb', 'aa:aa:aa:aa:aa:aa']
+
+ # Create a VIF with aa:aa:aa:aa:aa:aa
+ crash_test_dummy_vif = {
+ 'address': macs[1],
+ 'instance_uuid': 'fake_uuid',
+ 'network_id': 'fake_net',
+ 'uuid': 'fake_uuid',
+ }
+ self.network.db.virtual_interface_create(ctxt, crash_test_dummy_vif)
+
+ # Hand out a collision first, then a legit MAC
+ def fake_gen_mac():
+ return macs.pop()
+ self.stubs.Set(utils, 'generate_mac_address', fake_gen_mac)
+
+ # SQLite doesn't seem to honor the uniqueness constraint on the
+ # address column, so fake the collision-avoidance here
+ def fake_vif_save(vif):
+ if vif.address == crash_test_dummy_vif['address']:
+ raise exception.DBError("If you're smart, you'll retry!")
+ self.stubs.Set(models.VirtualInterface, 'save', fake_vif_save)
+
+ # Attempt to add another and make sure that both MACs are consumed
+ # by the retry loop
+ self.network.add_virtual_interface(ctxt, 'fake_uuid', 'fake_net')
+ self.assertEqual(macs, [])
+
class NetworkPolicyTestCase(test.TestCase):
def setUp(self):