public void DeleteShardAbortGSMDoAndLSMUndo() { bool shouldThrow = true; IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateRemoveShardOperationShardMapManagerIStoreShardMapIStoreShard = (_smm, _sm, _s) => { StubRemoveShardOperation op = new StubRemoveShardOperation(_smm, _sm, _s); op.CallBase = true; op.DoGlobalPostLocalExecuteIStoreTransactionScope = (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.DoGlobalPostLocalExecuteIStoreTransactionScope; op.DoGlobalPostLocalExecuteIStoreTransactionScope = null; try { return(op.DoGlobalPostLocalExecute(ts)); } finally { op.DoGlobalPostLocalExecuteIStoreTransactionScope = original; } } }; op.UndoLocalSourceExecuteIStoreTransactionScope = (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.UndoLocalSourceExecuteIStoreTransactionScope; op.UndoLocalSourceExecuteIStoreTransactionScope = null; try { return(op.UndoLocalSourceExecute(ts)); } finally { op.UndoLocalSourceExecuteIStoreTransactionScope = 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); ShardMap sm = smm.GetShardMap(ShardMapTests.s_defaultShardMapName); Assert.IsNotNull(sm); ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapTests.s_shardedDBs[0]); Shard sNew = sm.CreateShard(sl); Assert.IsNotNull(sNew); bool storeOperationFailed = false; try { sm.DeleteShard(sNew); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.ShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); // verify that the shard exists in store. Shard sValidate = sm.GetShard(sl); Assert.IsNotNull(sValidate); // Obtain the pending operations. var pendingOperations = ShardMapperTests.GetPendingStoreOperations(); Assert.AreEqual(pendingOperations.Count(), 1); shouldThrow = false; storeOperationFailed = false; try { sm.DeleteShard(sNew); } catch (ShardManagementException) { storeOperationFailed = true; } Assert.IsFalse(storeOperationFailed); Assert.AreEqual(0, sm.GetShards().Count()); }
public void UpdateRangeMappingLocationAbortGSMPostLocalDoAndLSMTargetUndo() { bool shouldThrow = false; IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateUpdateMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingIStoreMappingStringGuid = (_smm, _opcode, _ssm, _sms, _smt, _p, _loid) => { StubUpdateMappingOperation op = new StubUpdateMappingOperation(_smm, _opcode, _ssm, _sms, _smt, _p, _loid); op.CallBase = true; op.DoGlobalPostLocalExecuteIStoreTransactionScope = (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.DoGlobalPostLocalExecuteIStoreTransactionScope; op.DoGlobalPostLocalExecuteIStoreTransactionScope = null; try { return op.DoGlobalPostLocalExecute(ts); } finally { op.DoGlobalPostLocalExecuteIStoreTransactionScope = original; } } }; op.UndoLocalTargetExecuteIStoreTransactionScope = (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.UndoLocalTargetExecuteIStoreTransactionScope; op.UndoLocalTargetExecuteIStoreTransactionScope = null; try { return op.UndoLocalTargetExecute(ts); } finally { op.UndoLocalTargetExecuteIStoreTransactionScope = 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 sl1 = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[0]); Shard s1 = rsm.CreateShard(sl1); Assert.IsNotNull(s1); ShardLocation sl2 = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[1]); Shard s2 = rsm.CreateShard(sl2); Assert.IsNotNull(s2); RangeMapping<int> r1 = rsm.CreateRangeMapping(new Range<int>(1, 20), s1); RangeMappingUpdate ru1 = new RangeMappingUpdate(); // Take the mapping offline first. ru1.Status = MappingStatus.Offline; RangeMapping<int> rNew = rsm.UpdateMapping(r1, ru1); Assert.IsNotNull(rNew); RangeMappingUpdate ru2 = new RangeMappingUpdate(); ru2.Shard = s2; shouldThrow = true; bool storeOperationFailed = false; try { rNew = rsm.UpdateMapping(rNew, ru2); Assert.IsNotNull(rNew); } 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: validate location of the mapping. RangeMapping<int> rValidate = rsm.GetMappingForKey(1); Assert.AreEqual(s1.Id, rValidate.Shard.Id); #region OpenConnection with Validation // Validation should fail with mapping does not exist since source mapping was deleted. bool validationFailed = false; try { using (SqlConnection conn = rsm.OpenConnection( rValidate, Globals.ShardUserConnectionString, ConnectionOptions.Validate)) { } } catch (ShardManagementException smme) { validationFailed = true; Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingDoesNotExist); } Assert.AreEqual(true, validationFailed); #endregion OpenConnection with Validation shouldThrow = false; // Removal should succeed now. storeOperationFailed = false; try { rsm.DeleteMapping(rNew); } catch (ShardManagementException) { storeOperationFailed = true; } Assert.IsFalse(storeOperationFailed); }
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 DeleteRangeMappingAbortLSMDoAndGSMUndo() { bool shouldThrow = true; IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateRemoveMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingGuid = (_smm, _opcode, _ssm, _sm, _loid) => { StubRemoveMappingOperation op = new StubRemoveMappingOperation(_smm, _opcode, _ssm, _sm, _loid); 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, 10), s); Assert.IsNotNull(r1); RangeMappingUpdate ru = new RangeMappingUpdate(); ru.Status = MappingStatus.Offline; // The mapping must be made offline before it can be deleted. r1 = rsm.UpdateMapping(r1, ru); Assert.AreEqual(MappingStatus.Offline, r1.Status); bool storeOperationFailed = false; try { rsm.DeleteMapping(r1); } 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: lookup for 5 still returns a valid mapping since we never committed the remove. RangeMapping<int> rValidate = rsm.GetMappingForKey(5); Assert.IsNotNull(rValidate); Assert.AreEqual(rValidate.Range, r1.Range); #region OpenConnection with Validation // Validation should fail with mapping is offline error since local mapping was not deleted. bool validationFailed = false; try { using (SqlConnection conn = rsm.OpenConnection( rValidate, Globals.ShardUserConnectionString, ConnectionOptions.Validate)) { } } catch (ShardManagementException smme) { validationFailed = true; Assert.AreEqual(smme.ErrorCode, ShardManagementErrorCode.MappingIsOffline); } Assert.AreEqual(true, validationFailed); #endregion OpenConnection with Validation shouldThrow = false; // Now we try an AddOperation, which should fail since we still have the mapping. ShardManagementException exception = AssertExtensions.AssertThrows<ShardManagementException> (() => rsm.CreateRangeMapping(new Range<int>(1, 10), s)); Assert.IsTrue( exception.ErrorCode == ShardManagementErrorCode.MappingRangeAlreadyMapped && exception.ErrorCategory == ShardManagementErrorCategory.RangeShardMap, "Expected MappingRangeAlreadyMapped error!"); // No pending operation should be left now since the previous operation took care of it. pendingOperations = ShardMapperTests.GetPendingStoreOperations(); Assert.AreEqual(pendingOperations.Count(), 0); // Removal should succeed now. storeOperationFailed = false; try { rsm.DeleteMapping(r1); } catch (ShardManagementException) { storeOperationFailed = true; } Assert.IsFalse(storeOperationFailed); }
public void UpdateRangeMappingOfflineAbortGSMDoAndGSMUndoPostLocal() { bool shouldThrow = true; IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateUpdateMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingIStoreMappingStringGuid = (_smm, _opcode, _ssm, _sms, _smt, _p, _loid) => { StubUpdateMappingOperation op = new StubUpdateMappingOperation(_smm, _opcode, _ssm, _sms, _smt, _p, _loid); op.CallBase = true; op.DoGlobalPostLocalExecuteIStoreTransactionScope = (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.DoGlobalPostLocalExecuteIStoreTransactionScope; op.DoGlobalPostLocalExecuteIStoreTransactionScope = null; try { return op.DoGlobalPostLocalExecute(ts); } finally { op.DoGlobalPostLocalExecuteIStoreTransactionScope = original; } } }; op.UndoLocalSourceExecuteIStoreTransactionScope = (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.UndoLocalSourceExecuteIStoreTransactionScope; op.UndoLocalSourceExecuteIStoreTransactionScope = null; try { return op.UndoLocalSourceExecute(ts); } finally { op.UndoLocalSourceExecuteIStoreTransactionScope = 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); RangeMappingUpdate ru = new RangeMappingUpdate() { Status = MappingStatus.Offline }; RangeMapping<int> rNew; bool storeOperationFailed = false; try { rNew = rsm.UpdateMapping(r1, ru); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.RangeShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); // Validation: check that custom is unchanged. RangeMapping<int> rValidate = rsm.GetMappingForKey(1); Assert.AreEqual(r1.Status, rValidate.Status); shouldThrow = false; rNew = rsm.UpdateMapping(r1, ru); Assert.IsNotNull(rNew); Assert.AreEqual(rNew.Status, ru.Status); }
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()); }
public void AddPointMappingAbortGSMDoAndGSMUndo() { bool shouldThrow = true; IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateAddMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMapping = (_smm, _opcode, _ssm, _sm) => { StubAddMappingOperation op = new StubAddMappingOperation(_smm, _opcode, _ssm, _sm); op.CallBase = true; op.DoGlobalPostLocalExecuteIStoreTransactionScope = (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.DoGlobalPostLocalExecuteIStoreTransactionScope; op.DoGlobalPostLocalExecuteIStoreTransactionScope = null; try { return op.DoGlobalPostLocalExecute(ts); } finally { op.DoGlobalPostLocalExecuteIStoreTransactionScope = 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); ListShardMap<int> lsm = smm.GetListShardMap<int>(ShardMapperTests.s_listShardMapName); Assert.IsNotNull(lsm); ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[0]); ShardLocation sl2 = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[1]); Shard s = lsm.CreateShard(sl); Assert.IsNotNull(s); Shard s2 = lsm.CreateShard(sl2); Assert.IsNotNull(s2); bool storeOperationFailed = false; try { PointMapping<int> p1 = lsm.CreatePointMapping(2, s); Assert.IsNotNull(p1); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.ListShardMap, 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); shouldThrow = false; // Validation: Adding same mapping again even at different location should succeed. PointMapping<int> p2 = lsm.CreatePointMapping(2, s2); Assert.IsNotNull(p2); pendingOperations = ShardMapperTests.GetPendingStoreOperations(); Assert.AreEqual(pendingOperations.Count(), 0); }
public void DeleteRangeMappingAbortLSM() { IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateRemoveMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingGuid = (_smm, _opcode, _ssm, _sm, _loid) => { StubRemoveMappingOperation op = new StubRemoveMappingOperation(_smm, _opcode, _ssm, _sm, _loid); 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); 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, 10), s); Assert.IsNotNull(r1); RangeMappingUpdate ru = new RangeMappingUpdate(); ru.Status = MappingStatus.Offline; // The mapping must be made offline before it can be deleted. r1 = rsm.UpdateMapping(r1, ru); Assert.AreEqual(MappingStatus.Offline, r1.Status); bool storeOperationFailed = false; try { rsm.DeleteMapping(r1); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.RangeShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); // Validation: lookup for 5 returns a valid mapping. RangeMapping<int> rValidate = rsm.GetMappingForKey(5); Assert.IsNotNull(rValidate); }
public void UpdateRangeMappingLocationAbortLSM() { bool shouldThrow = false; IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateUpdateMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingIStoreMappingStringGuid = (_smm, _opcode, _ssm, _sms, _smt, _p, _loid) => { StubUpdateMappingOperation op = new StubUpdateMappingOperation(_smm, _opcode, _ssm, _sms, _smt, _p, _loid); op.CallBase = true; if (shouldThrow) { // Abort on source. 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); ShardLocation sl1 = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[0]); Shard s1 = rsm.CreateShard(sl1); Assert.IsNotNull(s1); ShardLocation sl2 = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[1]); Shard s2 = rsm.CreateShard(sl2); Assert.IsNotNull(s2); RangeMapping<int> r1 = rsm.CreateRangeMapping(new Range<int>(1, 20), s1); RangeMappingUpdate ru1 = new RangeMappingUpdate(); // Take the mapping offline first. ru1.Status = MappingStatus.Offline; RangeMapping<int> rNew = rsm.UpdateMapping(r1, ru1); Assert.IsNotNull(rNew); RangeMappingUpdate ru2 = new RangeMappingUpdate(); ru2.Shard = s2; shouldThrow = true; bool storeOperationFailed = false; try { rNew = rsm.UpdateMapping(rNew, ru2); Assert.IsNotNull(rNew); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.RangeShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); // validation: validate location of the mapping. RangeMapping<int> rValidate = rsm.GetMappingForKey(1); Assert.AreEqual(s1.Id, rValidate.Shard.Id); }
public void AddRangeMappingAbortLSM() { bool shouldThrow = true; IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateAddMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMapping = (_smm, _opcode, _ssm, _sm) => { StubAddMappingOperation op = new StubAddMappingOperation(_smm, _opcode, _ssm, _sm); 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; } } }; 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); bool storeOperationFailed = false; try { RangeMapping<int> r1 = rsm.CreateRangeMapping(new Range<int>(1, 10), s); Assert.IsNotNull(r1); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.RangeShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); shouldThrow = false; // validation: adding same range mapping again will succeed. RangeMapping<int> rValidate = rsm.CreateRangeMapping(new Range<int>(1, 10), s); Assert.IsNotNull(rValidate); }
public void UpdatePointMappingAbortLSM() { IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateUpdateMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingIStoreMappingStringGuid = (_smm, _opcode, _ssm, _sms, _smt, _p, _loid) => { StubUpdateMappingOperation op = new StubUpdateMappingOperation(_smm, _opcode, _ssm, _sms, _smt, _p, _loid); 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); ListShardMap<int> lsm = smm.GetListShardMap<int>(ShardMapperTests.s_listShardMapName); Assert.IsNotNull(lsm); ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[0]); Shard s = lsm.CreateShard(sl); Assert.IsNotNull(s); PointMapping<int> p1 = lsm.CreatePointMapping(1, s); // Take the mapping offline first before the shard location can be updated. PointMappingUpdate pu = new PointMappingUpdate() { Status = MappingStatus.Offline }; bool storeOperationFailed = false; try { PointMapping<int> pNew = lsm.UpdateMapping(p1, pu); Assert.IsNotNull(pNew); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.ListShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); // validation: validate custom field of the mapping. PointMapping<int> pValidate = lsm.GetMappingForKey(1); Assert.AreEqual(p1.Status, pValidate.Status); }
public void DeletePointMappingAbortGSM() { IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateRemoveMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingGuid = (_smm, _opcode, _ssm, _sm, _loid) => { StubRemoveMappingOperation op = new StubRemoveMappingOperation(_smm, _opcode, _ssm, _sm, _loid); op.CallBase = true; op.DoGlobalPostLocalExecuteIStoreTransactionScope = (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); ListShardMap<int> lsm = smm.GetListShardMap<int>(ShardMapperTests.s_listShardMapName); Assert.IsNotNull(lsm); ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapperTests.s_shardedDBs[0]); Shard s = lsm.CreateShard(sl); Assert.IsNotNull(s); PointMapping<int> p1 = lsm.CreatePointMapping(1, s); PointMapping<int> pmOffline = lsm.MarkMappingOffline(p1); Assert.IsNotNull(pmOffline); bool storeOperationFailed = false; try { lsm.DeleteMapping(pmOffline); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.ListShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); // validation: Lookup point will succeed. PointMapping<int> pNew = lsm.GetMappingForKey(1); Assert.IsNotNull(pNew); }
/// <summary> /// OpenConnectionForKey for unavailable server using RangeShardMap. /// </summary> /// <param name="openConnectionAsync">Whether the connection should be opened asynchronously</param> private void UnavailableServerOpenConnectionForKeyRangeShardMapInternal(bool openConnectionAsync = false) { StubSqlStoreConnectionFactory scf = null; bool shouldThrow = false; scf = new StubSqlStoreConnectionFactory() { CallBase = true, GetUserConnectionString = (cstr) => { if (shouldThrow) { throw ShardMapFaultHandlingTests.TransientSqlException; } else { var original = scf.GetUserConnectionString; scf.GetUserConnectionString = null; try { return scf.GetUserConnection(cstr); } finally { scf.GetUserConnectionString = original; } } } }; int callCount = 0; // Counting implementation of FindMappingByKey IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateFindMappingByKeyGlobalOperationShardMapManagerStringIStoreShardMapShardKeyCacheStoreMappingUpdatePolicyShardManagementErrorCategoryBooleanBoolean = (_smm, _opname, _ssm, _sk, _pol, _ec, _cr, _if) => { StubFindMappingByKeyGlobalOperation op = new StubFindMappingByKeyGlobalOperation(_smm, _opname, _ssm, _sk, _pol, _ec, _cr, _if); op.CallBase = true; op.DoGlobalExecuteIStoreTransactionScope = (ts) => { callCount++; // Call the base function, hack for this behavior is to save current operation, set current to null, restore current operation. var original = op.DoGlobalExecuteIStoreTransactionScope; op.DoGlobalExecuteIStoreTransactionScope = null; try { return op.DoGlobalExecute(ts); } finally { op.DoGlobalExecuteIStoreTransactionScope = original; } }; op.DoGlobalExecuteAsyncIStoreTransactionScope = (ts) => Task.FromResult<IStoreResults>(op.DoGlobalExecuteIStoreTransactionScope(ts)); return op; } }; StubCacheStore scs = null; ICacheStoreMapping currentMapping = null; StubICacheStoreMapping sics = new StubICacheStoreMapping { MappingGet = () => currentMapping.Mapping, CreationTimeGet = () => currentMapping.CreationTime, TimeToLiveMillisecondsGet = () => currentMapping.TimeToLiveMilliseconds, ResetTimeToLive = () => currentMapping.ResetTimeToLive(), HasTimeToLiveExpired = () => currentMapping.HasTimeToLiveExpired() }; scs = new StubCacheStore() { CallBase = true, LookupMappingByKeyIStoreShardMapShardKey = (_ssm, _sk) => { var original = scs.LookupMappingByKeyIStoreShardMapShardKey; scs.LookupMappingByKeyIStoreShardMapShardKey = null; try { currentMapping = scs.LookupMappingByKey(_ssm, _sk); return sics; } finally { scs.LookupMappingByKeyIStoreShardMapShardKey = original; } } }; ShardMapManager smm = new ShardMapManager( new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString), scf, sof, scs, ShardMapManagerLoadPolicy.Lazy, RetryPolicy.DefaultRetryPolicy, 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>(5, 20), s); Assert.IsNotNull(r1); // Mapping is there, now let's try to abort the OpenConnectionForKey shouldThrow = true; bool failed = false; for (int i = 1; i <= 10; i++) { failed = false; try { if (openConnectionAsync) { rsm.OpenConnectionForKeyAsync(10, Globals.ShardUserConnectionString).Wait(); } else { rsm.OpenConnectionForKey(10, Globals.ShardUserConnectionString); } } catch (Exception ex) { if (ex is AggregateException) { ex = ex.InnerException as SqlException; } if (ex is SqlException) { failed = true; } } Assert.IsTrue(failed); } Assert.AreEqual(1, callCount); long currentTtl = ((ICacheStoreMapping)sics).TimeToLiveMilliseconds; Assert.IsTrue(currentTtl > 0); // Let's fake the TTL to be 0, to force another call to store. sics.TimeToLiveMillisecondsGet = () => 0; sics.HasTimeToLiveExpired = () => true; failed = false; try { if (openConnectionAsync) { rsm.OpenConnectionForKeyAsync(12, Globals.ShardUserConnectionString).Wait(); } else { rsm.OpenConnectionForKey(12, Globals.ShardUserConnectionString); } } catch (Exception ex) { if (ex is AggregateException) { ex = ex.InnerException as SqlException; } if (ex is SqlException) { failed = true; } } Assert.IsTrue(failed); Assert.AreEqual(2, callCount); sics.TimeToLiveMillisecondsGet = () => currentMapping.TimeToLiveMilliseconds; sics.HasTimeToLiveExpired = () => currentMapping.HasTimeToLiveExpired(); failed = false; try { if (openConnectionAsync) { rsm.OpenConnectionForKeyAsync(15, Globals.ShardUserConnectionString).Wait(); } else { rsm.OpenConnectionForKey(15, Globals.ShardUserConnectionString); } } catch (Exception ex) { if (ex is AggregateException) { ex = ex.InnerException as SqlException; } if (ex is SqlException) { failed = true; } } Assert.IsTrue(failed); Assert.IsTrue(((ICacheStoreMapping)sics).TimeToLiveMilliseconds > currentTtl); shouldThrow = false; failed = false; try { if (openConnectionAsync) { rsm.OpenConnectionForKeyAsync(7, Globals.ShardUserConnectionString).Wait(); } else { rsm.OpenConnectionForKey(7, Globals.ShardUserConnectionString); } } catch (Exception ex) { if (ex is AggregateException) { ex = ex.InnerException as SqlException; } if (ex is SqlException) { failed = true; } } Assert.IsFalse(failed); Assert.AreEqual(0, ((ICacheStoreMapping)sics).TimeToLiveMilliseconds); }
public void DeleteShardAbortGSMDoAndLSMUndo() { bool shouldThrow = true; IStoreOperationFactory sof = new StubStoreOperationFactory() { CallBase = true, CreateRemoveShardOperationShardMapManagerIStoreShardMapIStoreShard = (_smm, _sm, _s) => { StubRemoveShardOperation op = new StubRemoveShardOperation(_smm, _sm, _s); op.CallBase = true; op.DoGlobalPostLocalExecuteIStoreTransactionScope = (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.DoGlobalPostLocalExecuteIStoreTransactionScope; op.DoGlobalPostLocalExecuteIStoreTransactionScope = null; try { return op.DoGlobalPostLocalExecute(ts); } finally { op.DoGlobalPostLocalExecuteIStoreTransactionScope = original; } } }; op.UndoLocalSourceExecuteIStoreTransactionScope = (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.UndoLocalSourceExecuteIStoreTransactionScope; op.UndoLocalSourceExecuteIStoreTransactionScope = null; try { return op.UndoLocalSourceExecute(ts); } finally { op.UndoLocalSourceExecuteIStoreTransactionScope = 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); ShardMap sm = smm.GetShardMap(ShardMapTests.s_defaultShardMapName); Assert.IsNotNull(sm); ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapTests.s_shardedDBs[0]); Shard sNew = sm.CreateShard(sl); Assert.IsNotNull(sNew); bool storeOperationFailed = false; try { sm.DeleteShard(sNew); } catch (ShardManagementException sme) { Assert.AreEqual(ShardManagementErrorCategory.ShardMap, sme.ErrorCategory); Assert.AreEqual(ShardManagementErrorCode.StorageOperationFailure, sme.ErrorCode); storeOperationFailed = true; } Assert.IsTrue(storeOperationFailed); // verify that the shard exists in store. Shard sValidate = sm.GetShard(sl); Assert.IsNotNull(sValidate); // Obtain the pending operations. var pendingOperations = ShardMapperTests.GetPendingStoreOperations(); Assert.AreEqual(pendingOperations.Count(), 1); shouldThrow = false; storeOperationFailed = false; try { sm.DeleteShard(sNew); } catch (ShardManagementException) { storeOperationFailed = true; } Assert.IsFalse(storeOperationFailed); Assert.AreEqual(0, sm.GetShards().Count()); }