@@ -1363,6 +1363,17 @@ def test_reshape(self):
1363
1363
resp = self .client ._reshape (self .context , inventories , allocs )
1364
1364
self .assertEqual (204 , resp .status_code )
1365
1365
1366
+ # Trigger generation conflict
1367
+ # We can do this is by simply sending back the same reshape as that
1368
+ # will not work because the previous reshape updated generations
1369
+ self .assertRaises (
1370
+ exception .PlacementReshapeConflict ,
1371
+ self .client ._reshape ,
1372
+ self .context ,
1373
+ inventories ,
1374
+ allocs ,
1375
+ )
1376
+
1366
1377
def test_update_from_provider_tree_reshape (self ):
1367
1378
"""Run update_from_provider_tree with reshaping."""
1368
1379
exp_ptree = self ._set_up_provider_tree ()
@@ -1519,3 +1530,44 @@ def test_update_from_provider_tree_reshape(self):
1519
1530
self .context , self .compute_name )
1520
1531
self .assertProviderTree (orig_exp_ptree , ptree )
1521
1532
self .assertAllocations (orig_exp_allocs , allocs )
1533
+
1534
+ def test_update_from_provider_tree_reshape_conflict_retry (self ):
1535
+ exp_ptree = self ._set_up_provider_tree ()
1536
+
1537
+ ptree = self .client .get_provider_tree_and_ensure_root (
1538
+ self .context , self .compute_uuid )
1539
+ allocs = self .client .get_allocations_for_provider_tree (
1540
+ self .context , self .compute_name )
1541
+ self .assertProviderTree (exp_ptree , ptree )
1542
+ self .assertAllocations ({}, allocs )
1543
+
1544
+ exp_allocs = self ._set_up_provider_tree_allocs ()
1545
+
1546
+ # we prepare inventory and allocation changes to trigger a reshape
1547
+ for rp_uuid in ptree .get_provider_uuids ():
1548
+ # Add a new resource class to the inventories
1549
+ ptree .update_inventory (
1550
+ rp_uuid , dict (ptree .data (rp_uuid ).inventory ,
1551
+ CUSTOM_FOO = {'total' : 10 }))
1552
+ exp_ptree [rp_uuid ]['inventory' ]['CUSTOM_FOO' ] = {'total' : 10 }
1553
+ for c_uuid , alloc in allocs .items ():
1554
+ for rp_uuid , res in alloc ['allocations' ].items ():
1555
+ res ['resources' ]['CUSTOM_FOO' ] = 1
1556
+ exp_allocs [c_uuid ]['allocations' ][rp_uuid ][
1557
+ 'resources' ]['CUSTOM_FOO' ] = 1
1558
+
1559
+ # As the inventory update happens is the same request as the allocation
1560
+ # update the allocation update will have a generation conflict.
1561
+ # So we expect that it is signalled with an exception so that the
1562
+ # upper layer can re-drive the reshape process with a fresh tree that
1563
+ # now has the inventories
1564
+ self .assertRaises (
1565
+ exception .PlacementReshapeConflict ,
1566
+ self .client .update_from_provider_tree ,
1567
+ self .context ,
1568
+ ptree ,
1569
+ allocations = allocs ,
1570
+ )
1571
+ # also we except that the internal caches is cleared so that the
1572
+ # re-drive will have a chance to load fresh data from placement
1573
+ self .assertEqual (0 , len (self .client ._provider_tree .roots ))
0 commit comments