public void TestRestoreGSMFromLSMsRangeWithGarbageInGSM() { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap<int> rsm = smm.GetRangeShardMap<int>(RecoveryManagerTests.s_rangeShardMapName); Assert.IsNotNull(rsm); IList<ShardLocation> sls = new List<ShardLocation>(); int i = 0; List<RangeMapping<int>> ranges = new List<RangeMapping<int>>(); foreach (string dbName in RecoveryManagerTests.s_shardedDBs) { ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, dbName); sls.Add(sl); Shard s = rsm.CreateShard(sl); Assert.IsNotNull(s); var r = rsm.CreateRangeMapping(new Range<int>(1 + i * 10, 10 + i * 10), s); Assert.IsNotNull(r); ranges.Add(r); i++; } // Perturb the mappings in the GSM. using (SqlConnection conn = new SqlConnection(Globals.ShardMapManagerTestConnectionString)) { conn.Open(); using (SqlCommand cmd = new SqlCommand(String.Format("update {0}.__ShardManagement.ShardMappingsGlobal set MaxValue = MaxValue + 1, MinValue = MinValue + 1", Globals.ShardMapManagerDatabaseName), conn)) { cmd.ExecuteNonQuery(); } } RecoveryManager rm = new RecoveryManager(smm); // Validate that we detect the inconsistencies in all the LSMs. foreach (ShardLocation sl in sls) { IEnumerable<RecoveryToken> gs = rm.DetectMappingDifferences(sl); Assert.AreEqual(1, gs.Count(), "The test environment was not expecting more than one local shardmap."); // Briefly validate that foreach (RecoveryToken g in gs) { var kvps = rm.GetMappingDifferences(g); Assert.AreEqual(2, kvps.Keys.Count, "The count of differences does not match the expected."); } } // Recover the LSM from the GSM rm.RebuildMappingsOnShardMapManagerFromShards(sls); // Validate that we fixed all the inconsistencies. foreach (ShardLocation sl in sls) { IEnumerable<RecoveryToken> gs = rm.DetectMappingDifferences(sl); // Briefly validate that foreach (RecoveryToken g in gs) { var kvps = rm.GetMappingDifferences(g); Assert.AreEqual(0, kvps.Keys.Count, "There were still differences after resolution."); } } }
public void TestRestoreGSMFromLSMsRange() { ShardMapManager smm = ShardMapManagerFactory.GetSqlShardMapManager( Globals.ShardMapManagerConnectionString, ShardMapManagerLoadPolicy.Lazy); RangeShardMap<int> rsm = smm.GetRangeShardMap<int>(RecoveryManagerTests.s_rangeShardMapName); Assert.IsNotNull(rsm); IList<ShardLocation> sls = new List<ShardLocation>(); int i = 0; List<RangeMapping<int>> ranges = new List<RangeMapping<int>>(); foreach (string dbName in RecoveryManagerTests.s_shardedDBs) { ShardLocation sl = new ShardLocation(Globals.ShardMapManagerTestsDatasourceName, dbName); sls.Add(sl); Shard s = rsm.CreateShard(sl); Assert.IsNotNull(s); var r = rsm.CreateRangeMapping(new Range<int>(1 + i * 10, 10 + i * 10), s); Assert.IsNotNull(r); ranges.Add(r); i++; } // Delete all mappings from GSM using (SqlConnection conn = new SqlConnection(Globals.ShardMapManagerTestConnectionString)) { conn.Open(); using (SqlCommand cmd = new SqlCommand(String.Format("delete from {0}.__ShardManagement.ShardMappingsGlobal", Globals.ShardMapManagerDatabaseName), conn)) { cmd.ExecuteNonQuery(); } } RecoveryManager rm = new RecoveryManager(smm); // Validate that we detect the inconsistencies in all the LSMs. foreach (ShardLocation sl in sls) { IEnumerable<RecoveryToken> gs = rm.DetectMappingDifferences(sl); Assert.AreEqual(1, gs.Count(), "The test environment was not expecting more than one local shardmap."); // Briefly validate that foreach (RecoveryToken g in gs) { var kvps = rm.GetMappingDifferences(g); Assert.AreEqual(1, kvps.Keys.Count, "The count of differences does not match the expected."); foreach (var kvp in kvps) { ShardRange range = kvp.Key; MappingLocation mappingLocation = kvp.Value; Assert.AreEqual(MappingLocation.MappingInShardOnly, mappingLocation, "An unexpected difference between global and local shardmaps was detected. This is likely a false positive and implies a bug in the detection code."); } } } // Recover the LSM from the GSM rm.RebuildMappingsOnShardMapManagerFromShards(sls); // Validate that we fixed all the inconsistencies. foreach (ShardLocation sl in sls) { IEnumerable<RecoveryToken> gs = rm.DetectMappingDifferences(sl); // Briefly validate that foreach (RecoveryToken g in gs) { var kvps = rm.GetMappingDifferences(g); Assert.AreEqual(0, kvps.Keys.Count, "There were still differences after resolution."); } } }