public void ShardMapOperationsFailureAfterLocalTarget()
        {
            StubStoreOperationFactory ssof = new StubStoreOperationFactory()
            {
                CallBase = true,

                CreateAddShardOperationShardMapManagerIStoreShardMapIStoreShard =
                (_smm, _sm, _s) => new AddShardOperationFailAfterLocalTarget(_smm, _sm, _s),

                CreateRemoveShardOperationShardMapManagerIStoreShardMapIStoreShard =
                (_smm, _sm, _s) => new RemoveShardOperationFailAfterLocalTarget(_smm, _sm, _s),

                CreateUpdateShardOperationShardMapManagerIStoreShardMapIStoreShardIStoreShard =
                (_smm, _sm, _sold, _snew) => new UpdateShardOperationFailAfterLocalTarget(_smm, _sm, _sold, _snew),

                CreateAddMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMapping =
                (_smm, _opcode, _ssm, _sm) => new AddMappingOperationFailAfterLocalTarget(_smm, _opcode, _ssm, _sm),

                CreateRemoveMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingGuid =
                (_smm, _opcode, _sm, _mapping, _loid) => new RemoveMappingOperationFailAfterLocalTarget(_smm, _opcode, _sm, _mapping, _loid),

                CreateUpdateMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingIStoreMappingStringGuid =
                (_shardMapManager, _operationCode, _shardMap, _mappingSource, _mappingTarget, _patternForKill, _lockOwnerId)
                    => new UpdateMappingOperationFailAfterLocalTarget(_shardMapManager, _operationCode, _shardMap, _mappingSource, _mappingTarget, _patternForKill, _lockOwnerId),

                CreateReplaceMappingsOperationShardMapManagerStoreOperationCodeIStoreShardMapTupleOfIStoreMappingGuidArrayTupleOfIStoreMappingGuidArray =
                (_smm, _opcode, _sm, _mappingsource, _mappingtarget) => new ReplaceMappingsOperationFailAfterLocalTarget(_smm, _opcode, _sm, _mappingsource, _mappingtarget)
            };

            ShardMapManager smm = new ShardMapManager(
                new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString),
                new SqlStoreConnectionFactory(),
                ssof,
                new CacheStore(),
                ShardMapManagerLoadPolicy.Lazy,
                new RetryPolicy(1, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero),
                RetryBehavior.DefaultRetryBehavior);

            RangeShardMap<int> rsm = smm.GetRangeShardMap<int>(ShardMapFaultHandlingTests.s_rangeShardMapName);

            Assert.IsNotNull(rsm);

            // test undo operations on shard

            // global pre-local only create shard
            Shard stemp = rsm.CreateShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapFaultHandlingTests.s_shardedDBs[0]));

            // now creating shard with GSM and LSM operations
            ssof.CreateAddShardOperationShardMapManagerIStoreShardMapIStoreShard = null;
            Shard s = rsm.CreateShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapFaultHandlingTests.s_shardedDBs[0]));

            // global pre-local only update shard

            rsm.UpdateShard(s, new ShardUpdate { Status = ShardStatus.Offline });

            // now update shard with GSM and LSM operations
            ssof.CreateUpdateShardOperationShardMapManagerIStoreShardMapIStoreShardIStoreShard = null;
            Shard sNew = rsm.UpdateShard(s, new ShardUpdate { Status = ShardStatus.Offline });

            // global pre-local only remove shard
            rsm.DeleteShard(sNew);

            // now remove with GSM and LSM operations
            ssof.CreateRemoveShardOperationShardMapManagerIStoreShardMapIStoreShard = null;
            rsm.DeleteShard(sNew);

            // test undo operations for shard mapings

            Shard s1 = rsm.CreateShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapFaultHandlingTests.s_shardedDBs[0]));

            Assert.IsNotNull(s1);

            Shard s2 = rsm.CreateShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapFaultHandlingTests.s_shardedDBs[1]));

            Assert.IsNotNull(s2);

            // first add mapping will just execute global pre-local and add operation into pending operations log
            RangeMapping<int> rtemp = rsm.CreateRangeMapping(new Range<int>(1, 10), s1);

            ssof.CreateAddMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMapping = null;

            // now add mapping will succeed after undoing pending operation

            RangeMapping<int> r1 = rsm.CreateRangeMapping(new Range<int>(1, 10), s1);

            Assert.IsNotNull(r1);

            RangeMappingUpdate ru = new RangeMappingUpdate { Status = MappingStatus.Offline };

            // below call will only execute global pre-local step to create operations log
            RangeMapping<int> r2 = rsm.UpdateMapping(r1, ru);

            ssof.CreateUpdateMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingIStoreMappingStringGuid = null;

            // now update same mapping again, this will undo previous pending operation and then add this mapping

            RangeMapping<int> r3 = rsm.UpdateMapping(r1, ru);

            // try mapping update failures with change in shard location
            // first reset CreateUpdateMappingOperation to just perform global pre-local
            ssof.CreateUpdateMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingIStoreMappingStringGuid =
                (_shardMapManager, _operationCode, _shardMap, _mappingSource, _mappingTarget, _patternForKill, _lockOwnerId)
                    => new UpdateMappingOperationFailAfterLocalTarget(_shardMapManager, _operationCode, _shardMap, _mappingSource, _mappingTarget, _patternForKill, _lockOwnerId);

            RangeMapping<int> r4 = rsm.UpdateMapping(r3, new RangeMappingUpdate { Shard = s2 });

            // now try with actual update mapping operation
            ssof.CreateUpdateMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingIStoreMappingStringGuid = null;
            RangeMapping<int> r5 = rsm.UpdateMapping(r3, new RangeMappingUpdate { Shard = s2 });

            // split mapping toperform gsm-only pre-local operation

            IReadOnlyList<RangeMapping<int>> rlisttemp = rsm.SplitMapping(r5, 5);

            // try actual operation which will undo previous pending op
            ssof.CreateReplaceMappingsOperationShardMapManagerStoreOperationCodeIStoreShardMapTupleOfIStoreMappingGuidArrayTupleOfIStoreMappingGuidArray = null;

            IReadOnlyList<RangeMapping<int>> rlist = rsm.SplitMapping(r5, 5);

            // remove mapping to create operations log and then exit
            rsm.DeleteMapping(rlist[0]);

            ssof.CreateRemoveMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMappingGuid = null;

            // now actually remove the mapping
            rsm.DeleteMapping(rlist[0]);
        }
        public void AddRangeMappingFailGSMAfterSuccessLSM()
        {
            StubStoreOperationFactory ssof = new StubStoreOperationFactory()
            {
                CallBase = true,
                CreateAddMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMapping =
                    (_smm, _opcode, _ssm, _sm) => new NTimeFailingAddMappingOperation(2, _smm, _opcode, _ssm, _sm)
            };

            ShardMapManager smm = new ShardMapManager(
                new SqlShardMapManagerCredentials(Globals.ShardMapManagerConnectionString),
                new SqlStoreConnectionFactory(),
                ssof,
                new CacheStore(),
                ShardMapManagerLoadPolicy.Lazy,
                new RetryPolicy(1, TimeSpan.Zero, TimeSpan.Zero, TimeSpan.Zero), RetryBehavior.DefaultRetryBehavior);

            RangeShardMap<int> rsm = smm.GetRangeShardMap<int>(ShardMapFaultHandlingTests.s_rangeShardMapName);

            Assert.IsNotNull(rsm);

            Shard s = rsm.CreateShard(new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, ShardMapFaultHandlingTests.s_shardedDBs[0]));

            Assert.IsNotNull(s);

            bool failed = false;

            try
            {
                // Inject GSM transaction failure at GSM commit time.
                RangeMapping<int> r1 = rsm.CreateRangeMapping(new Range<int>(1, 10), s);
            }
            catch (ShardManagementException)
            {
                failed = true;
            }

            Assert.IsTrue(failed);

            failed = false;

            ssof.CreateAddMappingOperationShardMapManagerStoreOperationCodeIStoreShardMapIStoreMapping = null;

            try
            {
                RangeMapping<int> r1 = rsm.CreateRangeMapping(new Range<int>(1, 10), s);
            }
            catch (ShardManagementException)
            {
                failed = true;
            }

            Assert.IsFalse(failed);
        }