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 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 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 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);
        }