summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Smith <danms@us.ibm.com>2012-10-26 14:32:10 -0700
committerDan Smith <danms@us.ibm.com>2012-10-26 14:32:10 -0700
commit91fb1ce5c8b8c11fb6e35d8774b7df48da0786b3 (patch)
tree45ae43b938fbce11af1eb3fb0a50fbf4f4a598a3
parent47e81951f7925ef506cd1ef8ba9262c127357d0c (diff)
downloadnova-91fb1ce5c8b8c11fb6e35d8774b7df48da0786b3.tar.gz
nova-91fb1ce5c8b8c11fb6e35d8774b7df48da0786b3.tar.xz
nova-91fb1ce5c8b8c11fb6e35d8774b7df48da0786b3.zip
Fix nova-network MAC collision logic
The exception being caught and transformed in sqlalchemy/api.py was incorrect, causing nova-network to miss it in the MAC collision retry loop. This patch corrects that and adds a test of the collision logic. Fixes bug 1059366 Change-Id: I6bf16c2f59f06c7e84441604b057afd8dfe6d709
-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 6dd57fc2f..c2ae1dc70 100644
--- a/nova/db/sqlalchemy/api.py
+++ b/nova/db/sqlalchemy/api.py
@@ -1271,7 +1271,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):