diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-10-29 01:59:25 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-10-29 01:59:25 +0000 |
| commit | 316d8b73e7b5eac4de0ef6c820595f47af6fb615 (patch) | |
| tree | f3ad43c4ccad215bcb3b76b1c15ebc2594fef6d5 | |
| parent | e8af7fb5d725287362323fe451593665cb5ce593 (diff) | |
| parent | 91fb1ce5c8b8c11fb6e35d8774b7df48da0786b3 (diff) | |
Merge "Fix nova-network MAC collision logic"
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 2 | ||||
| -rw-r--r-- | nova/tests/network/test_manager.py | 33 |
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): |
