API compare-and-swap updates based on revision_number
Allows posting revision number matching in the If-Match header
so updates/deletes will only be satisfied if the current revision
number of the object matches.
DocImpact: The Neutron API now supports conditional updates to resources
that contain the standard 'revision_number' attribute by
setting the revision_number in an HTTP If-Match header.
APIImpact
Partial-Bug: #1493714
Partially-Implements: blueprint push-notifications
Change-Id: I7d97d6044378eb59cb2c7bdc788dc6c174783299
diff --git a/neutron/tests/tempest/api/test_revisions.py b/neutron/tests/tempest/api/test_revisions.py
index d94aede..83c8410 100644
--- a/neutron/tests/tempest/api/test_revisions.py
+++ b/neutron/tests/tempest/api/test_revisions.py
@@ -13,6 +13,7 @@
import netaddr
from tempest.lib import decorators
+from tempest.lib import exceptions
from tempest import test
from neutron.tests.tempest.api import base
@@ -33,6 +34,35 @@
self.assertGreater(updated['network']['revision_number'],
net['revision_number'])
+ @decorators.idempotent_id('4a26a4be-9c53-483c-bc50-b11111113333')
+ def test_update_network_constrained_by_revision(self):
+ net = self.create_network()
+ current = net['revision_number']
+ stale = current - 1
+ # using a stale number should fail
+ self.assertRaises(
+ exceptions.PreconditionFailed,
+ self.client.update_network,
+ net['id'], name='newnet',
+ headers={'If-Match': 'revision_number=%s' % stale}
+ )
+
+ # using current should pass. in case something is updating the network
+ # on the server at the same time, we have to re-read and update to be
+ # safe
+ for i in range(100):
+ current = (self.client.show_network(net['id'])
+ ['network']['revision_number'])
+ try:
+ self.client.update_network(
+ net['id'], name='newnet',
+ headers={'If-Match': 'revision_number=%s' % current})
+ except exceptions.UnexpectedResponseCode:
+ continue
+ break
+ else:
+ self.fail("Failed to update network after 100 tries.")
+
@decorators.idempotent_id('cac7ecde-12d5-4331-9a03-420899dea077')
def test_update_port_bumps_revision(self):
net = self.create_network()