public void MergeRangeMappingAbortSourceLocalDoAndGSMPostLocalUndo() { bool shouldThrow = true; IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateReplaceMappingsOperationShardMapManagerStoreOperationCodeIStoreShardMapTupleOfIStoreMappingGuidArrayTupleOfIStoreMappingGuidArray = (_smm, _opcode, _ssm, _smo, _smn) => { StubReplaceMappingsOperation op = new StubReplaceMappingsOperation(_smm, _opcode, _ssm, _smo, _smn); op.CallBase = true; op.DoLocalSourceExecuteIStoreTransactionScope = (ts) => { if (shouldThrow) { throw new StoreException("", ShardMapFaultHandlingTests.TransientSqlException); } else { // Call the base function, hack for this behavior is to save current operation, set current to null, restore current operation. var original = op.DoLocalSourceExecuteIStoreTransactionScope; op.DoLocalSourceExecuteIStoreTransactionScope = null; try { return op.DoLocalSourceExecute(ts); } finally { op.DoLocalSourceExecuteIStoreTransactionScope = original; } } }; op.UndoGlobalPostLocalExecuteIStoreTransactionScope = (ts) => { if (shouldThrow) { throw new StoreException("", ShardMapFaultHandlingTests.TransientSqlException); } else { // Call the base function, hack for this behavior is to save current operation, set current to null, restore current operation. var original = op.UndoGlobalPostLocalExecuteIStoreTransactionScope; op.UndoGlobalPostLocalExecuteIStoreTransactionScope = null; try { return op.UndoGlobalPostLocalExecute(ts); } finally { op.UndoGlobalPostLocalExecuteIStoreTransactionScope = original; } } }; return op; } }; ShardMapManager smm = new ShardMapManager( new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString), new SqlStoreConnectionFactory(), sof, new CacheStore(), ShardMapManagerLoadPolicy.Lazy, new RetryPolicy(1, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero), RetryBehavior.DefaultRetryBehavior); RangeShardMap<int> rsm = smm.GetRangeShardMap<int>(ShardMapperTests.s_rangeShardMapName); Assert.IsNotNull(rsm); ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[0]); Shard s = rsm.CreateShard(sl); Assert.IsNotNull(s); RangeMapping<int> r1 = rsm.CreateRangeMapping(new Range<int>(1, 20), s); RangeMapping<int> r2 = rsm.CreateRangeMapping(new Range<int>(20, 40), s); bool storeOperationFailed = false; try { RangeMapping<int> rMerged = rsm.MergeMappings(r1, r2); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.RangeShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); // Obtain the pending operations. var pendingOperations = ShardMapperTests.GetPendingStoreOperations(); Assert.AreEqual(pendingOperations.Count(), 1); // Validation: Mapping range is not updated - lookup for point 10 returns mapping with version 0. RangeMapping<int> rValidateLeft = rsm.GetMappingForKey(5); RangeMapping<int> rValidateRight = rsm.GetMappingForKey(25); Assert.AreEqual(r1.Range, rValidateLeft.Range); Assert.AreEqual(r2.Range, rValidateRight.Range); #region OpenConnection with Validation // Validation should succeed since source mapping was never deleted. bool validationFailed = false; try { using (SqlConnection conn = rsm.OpenConnection( rValidateLeft, Globals.ShardUserConnectionString, ConnectionOptions.Validate)) { } using (SqlConnection conn = rsm.OpenConnection( rValidateRight, Globals.ShardUserConnectionString, ConnectionOptions.Validate)) { } } catch (ShardManagementException) { validationFailed = true; } Assert.AreEqual(false, validationFailed); #endregion OpenConnection with Validation shouldThrow = false; // Split the range mapping on the left. storeOperationFailed = false; try { rsm.SplitMapping(r1, 10); } catch (ShardManagementException) { storeOperationFailed = true; } Assert.IsFalse(storeOperationFailed); }
public void MergeRangeMappingsAbortLSM() { IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateReplaceMappingsOperationShardMapManagerStoreOperationCodeIStoreShardMapTupleOfIStoreMappingGuidArrayTupleOfIStoreMappingGuidArray = (_smm, _opcode, _ssm, _smo, _smn) => { StubReplaceMappingsOperation op = new StubReplaceMappingsOperation(_smm, _opcode, _ssm, _smo, _smn); op.CallBase = true; op.DoLocalSourceExecuteIStoreTransactionScope = (ts) => { throw new StoreException("", ShardMapFaultHandlingTests.TransientSqlException); }; return op; } }; ShardMapManager smm = new ShardMapManager( new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString), new SqlStoreConnectionFactory(), sof, new CacheStore(), ShardMapManagerLoadPolicy.Lazy, new RetryPolicy(1, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero), RetryBehavior.DefaultRetryBehavior); RangeShardMap<int> rsm = smm.GetRangeShardMap<int>(ShardMapperTests.s_rangeShardMapName); Assert.IsNotNull(rsm); Shard s1 = rsm.CreateShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[0])); Assert.IsNotNull(s1); RangeMapping<int> r1 = rsm.CreateRangeMapping(new Range<int>(1, 10), s1); RangeMapping<int> r2 = rsm.CreateRangeMapping(new Range<int>(10, 20), s1); bool storeOperationFailed = false; try { RangeMapping<int> rMerged = rsm.MergeMappings(r1, r2); Assert.IsNotNull(rMerged); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.RangeShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); // Validation: get all mappings for [1,20) should return 2 mappings. Assert.AreEqual(2, rsm.GetMappings().Count()); }