public void MultipleTasksCanMakeChangesConcurrently() { var diffSet = new DiffSet <int>(Enumerable.Range(0, 100)); var diffPair = diffSet.GetDiff(); Assert.Equal(100, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); var tasks = new[] { Task.Factory.StartNew(() => { for (int i = 0; i < 50; i++) { Assert.True(diffSet.Remove(i)); } }), Task.Factory.StartNew(() => { for (int i = 100; i < 150; i++) { Assert.True(diffSet.Add(i)); } }) }; Task.WaitAll(tasks); Assert.Equal(100, diffSet.GetSnapshot().Count); for (int i = 50; i < 150; i++) { Assert.True(diffSet.Contains(i)); } diffPair = diffSet.GetDiff(); Assert.Equal(50, diffPair.Added.Count); Assert.Equal(50, diffPair.Removed.Count); Assert.False(diffPair.Reset); for (int i = 0; i < 50; i++) { Assert.False(diffSet.Contains(i)); Assert.False(diffPair.Added.Contains(i)); Assert.True(diffPair.Removed.Contains(i)); } for (int i = 50; i < 100; i++) { Assert.True(diffSet.Contains(i)); Assert.False(diffPair.Added.Contains(i)); Assert.False(diffPair.Removed.Contains(i)); } for (int i = 100; i < 50; i++) { Assert.True(diffSet.Contains(i)); Assert.True(diffPair.Added.Contains(i)); Assert.False(diffPair.Removed.Contains(i)); } }
public void GroupTokenIsNotNullWhenGroupsChange() { var response = new PersistentResponse(); var groupSet = new DiffSet<string>(new string[] { "a", "b", "c", "d" }); groupSet.GetDiff(); groupSet.Add("g"); var serializer = new Mock<IJsonSerializer>(); HashSet<string> results = null; serializer.Setup(m => m.Serialize(It.IsAny<object>(), It.IsAny<TextWriter>())) .Callback<object, TextWriter>((obj, tw) => { results = new HashSet<string>((IEnumerable<string>)obj); var jsonNet = new JsonNetSerializer(); jsonNet.Serialize(obj, tw); }); var protectedData = new Mock<IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); Connection.PopulateResponseState(response, groupSet, serializer.Object, protectedData.Object); Assert.NotNull(response.GroupsToken); Assert.True(results.Contains("a")); Assert.True(results.Contains("b")); Assert.True(results.Contains("c")); Assert.True(results.Contains("d")); Assert.True(results.Contains("g")); }
public void DiffPairMatchesSnapshotAfterConcurrentChanges() { var random = new Random(); var diffSet = new DiffSet <int>(Enumerable.Range(0, 5)); var localSet = new HashSet <int>(Enumerable.Range(0, 5)); Action updateSet = () => { for (int i = 0; i < 100; i++) { if (random.Next(2) == 1) { diffSet.Remove(random.Next(5)); } else { diffSet.Add(random.Next(5)); } } }; // Flush initial changes var diffPair = diffSet.GetDiff(); Assert.Equal(5, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 0; i < 10; i++) { Task.WaitAll(Enumerable.Repeat(updateSet, 10).Select(Task.Factory.StartNew).ToArray()); var snapShot = diffSet.GetSnapshot(); diffPair = diffSet.GetDiff(); Assert.False(diffPair.Reset); Assert.Equal(0, diffPair.Added.Intersect(diffPair.Removed).Count()); foreach (var addedItem in diffPair.Added) { Assert.True(localSet.Add(addedItem)); } foreach (var removedItem in diffPair.Removed) { Assert.True(localSet.Remove(removedItem)); } int numSharedItems = localSet.Intersect(snapShot).Count(); Assert.Equal(numSharedItems, snapShot.Count); Assert.Equal(numSharedItems, localSet.Count); } }
public void AddingAndRemovingSameItemMultipleTimesShowsUpOnceInTheDiff() { var diffSet = new DiffSet <int>(Enumerable.Range(0, 100)); Assert.False(diffSet.Add(0)); // no-op Assert.True(diffSet.Remove(99)); Assert.False(diffSet.Remove(99)); // no-op Assert.Equal(99, diffSet.GetSnapshot().Count); var diffPair = diffSet.GetDiff(); Assert.Equal(99, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 0; i < 99; i++) { Assert.True(diffPair.Added.Contains(i)); Assert.True(diffSet.Contains(i)); } Assert.False(diffSet.Add(1)); // no-op Assert.True(diffSet.Add(99)); Assert.False(diffSet.Add(99)); // no-op Assert.False(diffSet.Remove(101)); // no-op Assert.True(diffSet.Remove(0)); Assert.False(diffSet.Remove(0)); // no-op Assert.Equal(99, diffSet.GetSnapshot().Count); diffPair = diffSet.GetDiff(); Assert.Equal(1, diffPair.Added.Count); Assert.Equal(1, diffPair.Removed.Count); Assert.False(diffPair.Reset); Assert.True(diffPair.Added.Contains(99)); Assert.True(diffPair.Removed.Contains(0)); for (int i = 1; i < 100; i++) { Assert.True(diffSet.Contains(i)); } }
public void AddingAndRemovingSameItemDoesNotShowUpInDiff() { var diffSet = new DiffSet <int>(Enumerable.Range(0, 100)); Assert.True(diffSet.Add(100)); Assert.True(diffSet.Remove(98)); Assert.True(diffSet.Remove(99)); Assert.True(diffSet.Remove(100)); Assert.True(diffSet.Add(99)); Assert.True(diffSet.Add(98)); Assert.Equal(100, diffSet.GetSnapshot().Count); var diffPair = diffSet.GetDiff(); Assert.Equal(100, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 0; i < 100; i++) { Assert.True(diffPair.Added.Contains(i)); Assert.True(diffSet.Contains(i)); } Assert.True(diffSet.Add(150)); Assert.True(diffSet.Add(200)); Assert.True(diffSet.Remove(50)); Assert.True(diffSet.Remove(200)); Assert.True(diffSet.Remove(150)); Assert.True(diffSet.Add(50)); Assert.Equal(100, diffSet.GetSnapshot().Count); diffPair = diffSet.GetDiff(); Assert.Equal(0, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.False(diffPair.Reset); for (int i = 0; i < 100; i++) { Assert.True(diffSet.Contains(i)); } }
public void AddingAndRemovingSameItemDoesNotShowUpInDiff() { var diffSet = new DiffSet<int>(Enumerable.Range(0, 100)); Assert.True(diffSet.Add(100)); Assert.True(diffSet.Remove(98)); Assert.True(diffSet.Remove(99)); Assert.True(diffSet.Remove(100)); Assert.True(diffSet.Add(99)); Assert.True(diffSet.Add(98)); Assert.Equal(100, diffSet.GetSnapshot().Count); var diffPair = diffSet.GetDiff(); Assert.Equal(100, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 0; i < 100; i++) { Assert.True(diffPair.Added.Contains(i)); Assert.True(diffSet.Contains(i)); } Assert.True(diffSet.Add(150)); Assert.True(diffSet.Add(200)); Assert.True(diffSet.Remove(50)); Assert.True(diffSet.Remove(200)); Assert.True(diffSet.Remove(150)); Assert.True(diffSet.Add(50)); Assert.Equal(100, diffSet.GetSnapshot().Count); diffPair = diffSet.GetDiff(); Assert.Equal(0, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.False(diffPair.Reset); for (int i = 0; i < 100; i++) { Assert.True(diffSet.Contains(i)); } }
public void GroupTokenIsNullWhenNoNewGroups() { var response = new PersistentResponse(); var groupSet = new DiffSet<string>(new string[] { "a", "b", "c" }); // Get the first diff groupSet.GetDiff(); var serializer = new JsonNetSerializer(); var protectedData = new Mock<IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny<string>(), It.IsAny<string>())) .Returns<string, string>((value, purpose) => value); Connection.PopulateResponseState(response, groupSet, serializer, protectedData.Object); Assert.Null(response.GroupsToken); }
public void GroupTokenIsNullWhenNoNewGroups() { var response = new PersistentResponse(); var groupSet = new DiffSet <string>(new string[] { "a", "b", "c" }); // Get the first diff groupSet.GetDiff(); var serializer = new JsonNetSerializer(); var protectedData = new Mock <IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); Connection.PopulateResponseState(response, groupSet, serializer, protectedData.Object, connectionId: null); Assert.Null(response.GroupsToken); }
public void GroupTokenIsNotNullWhenGroupsChange() { var response = new PersistentResponse(); var groupSet = new DiffSet <string>(new string[] { "a:1", "b:2", "c", "d" }); groupSet.GetDiff(); groupSet.Add("g"); var serializer = new Mock <IJsonSerializer>(); HashSet <string> results = null; serializer.Setup(m => m.Serialize(It.IsAny <object>(), It.IsAny <TextWriter>())) .Callback <object, TextWriter>((obj, tw) => { results = new HashSet <string>((IEnumerable <string>)obj); var jsonNet = new JsonNetSerializer(); jsonNet.Serialize(obj, tw); }); var protectedData = new Mock <IProtectedData>(); protectedData.Setup(m => m.Protect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); protectedData.Setup(m => m.Unprotect(It.IsAny <string>(), It.IsAny <string>())) .Returns <string, string>((value, purpose) => value); Connection.PopulateResponseState(response, groupSet, serializer.Object, protectedData.Object, connectionId: "myconnection"); Assert.NotNull(response.GroupsToken); var parts = response.GroupsToken.Split(new[] { ':' }, 2); Assert.Equal(2, parts.Length); Assert.Equal("myconnection", parts[0]); Assert.True(results.Contains("a:1")); Assert.True(results.Contains("b:2")); Assert.True(results.Contains("c")); Assert.True(results.Contains("d")); Assert.True(results.Contains("g")); }
public void AddingAndRemovingSameItemMultipleTimesShowsUpOnceInTheDiff() { var diffSet = new DiffSet<int>(Enumerable.Range(0, 100)); Assert.False(diffSet.Add(0)); // no-op Assert.True(diffSet.Remove(99)); Assert.False(diffSet.Remove(99)); // no-op Assert.Equal(99, diffSet.GetSnapshot().Count); var diffPair = diffSet.GetDiff(); Assert.Equal(99, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 0; i < 99; i++) { Assert.True(diffPair.Added.Contains(i)); Assert.True(diffSet.Contains(i)); } Assert.False(diffSet.Add(1)); // no-op Assert.True(diffSet.Add(99)); Assert.False(diffSet.Add(99)); // no-op Assert.False(diffSet.Remove(101)); // no-op Assert.True(diffSet.Remove(0)); Assert.False(diffSet.Remove(0)); // no-op Assert.Equal(99, diffSet.GetSnapshot().Count); diffPair = diffSet.GetDiff(); Assert.Equal(1, diffPair.Added.Count); Assert.Equal(1, diffPair.Removed.Count); Assert.False(diffPair.Reset); Assert.True(diffPair.Added.Contains(99)); Assert.True(diffPair.Removed.Contains(0)); for (int i = 1; i < 100; i++) { Assert.True(diffSet.Contains(i)); } }
public void InitialValueCombineWithChangesInFirstDiff() { var diffSet = new DiffSet <int>(Enumerable.Range(0, 100)); Assert.True(diffSet.Add(-1)); Assert.True(diffSet.Add(100)); Assert.True(diffSet.Remove(0)); Assert.True(diffSet.Remove(-1)); Assert.Equal(100, diffSet.GetSnapshot().Count); var diffPair = diffSet.GetDiff(); Assert.Equal(100, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 1; i <= 100; i++) { Assert.True(diffPair.Added.Contains(i)); Assert.True(diffSet.Contains(i)); } }
public void InitializeDiffSetWithChangingIEnumerable() { var diffSet = new DiffSet <int>(new NonResettingEnumerator().Ints(5)); Assert.Equal(5, diffSet.GetSnapshot().Count); for (int i = 0; i < 5; i++) { Assert.True(diffSet.Contains(i)); } var diffPair = diffSet.GetDiff(); Assert.Equal(5, diffSet.GetSnapshot().Count); Assert.Equal(5, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 0; i < 5; i++) { Assert.True(diffSet.Contains(i)); Assert.True(diffPair.Added.Contains(i)); Assert.False(diffPair.Removed.Contains(i)); } }
internal static void PopulateResponseState(PersistentResponse response, DiffSet<string> groupSet, IJsonSerializer serializer, IProtectedData protectedData) { DiffPair<string> groupDiff = groupSet.GetDiff(); if (groupDiff.AnyChanges) { // Create a protected payload of the sorted list IEnumerable<string> groups = groupSet.GetSnapshot(); // No groups so do nothing if (groups.Any()) { // Remove group prefixes before any thing goes over the wire string groupsString = serializer.Stringify(PrefixHelper.RemoveGroupPrefixes(groups)); // The groups token response.GroupsToken = protectedData.Protect(groupsString, Purposes.Groups); } } }
public void MultipleTasksCanMakeChangesConcurrently() { var diffSet = new DiffSet<int>(Enumerable.Range(0, 100)); var diffPair = diffSet.GetDiff(); Assert.Equal(100, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); var tasks = new[] { Task.Factory.StartNew(() => { for (int i = 0; i < 50; i++) { Assert.True(diffSet.Remove(i)); } }), Task.Factory.StartNew(() => { for (int i = 100; i < 150; i++) { Assert.True(diffSet.Add(i)); } }) }; Task.WaitAll(tasks); Assert.Equal(100, diffSet.GetSnapshot().Count); for (int i = 50; i < 150; i++) { Assert.True(diffSet.Contains(i)); } diffPair = diffSet.GetDiff(); Assert.Equal(50, diffPair.Added.Count); Assert.Equal(50, diffPair.Removed.Count); Assert.False(diffPair.Reset); for (int i = 0; i < 50; i++) { Assert.False(diffSet.Contains(i)); Assert.False(diffPair.Added.Contains(i)); Assert.True(diffPair.Removed.Contains(i)); } for (int i = 50; i < 100; i++) { Assert.True(diffSet.Contains(i)); Assert.False(diffPair.Added.Contains(i)); Assert.False(diffPair.Removed.Contains(i)); } for (int i = 100; i < 50; i++) { Assert.True(diffSet.Contains(i)); Assert.True(diffPair.Added.Contains(i)); Assert.False(diffPair.Removed.Contains(i)); } }
public void InitialValueCombineWithChangesInFirstDiff() { var diffSet = new DiffSet<int>(Enumerable.Range(0, 100)); Assert.True(diffSet.Add(-1)); Assert.True(diffSet.Add(100)); Assert.True(diffSet.Remove(0)); Assert.True(diffSet.Remove(-1)); Assert.Equal(100, diffSet.GetSnapshot().Count); var diffPair = diffSet.GetDiff(); Assert.Equal(100, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 1; i <= 100; i++) { Assert.True(diffPair.Added.Contains(i)); Assert.True(diffSet.Contains(i)); } }
public void InitializeDiffSetWithChangingIEnumerable() { var diffSet = new DiffSet<int>(new NonResettingEnumerator().Ints(5)); Assert.Equal(5, diffSet.GetSnapshot().Count); for (int i = 0; i < 5; i++ ) { Assert.True(diffSet.Contains(i)); } var diffPair = diffSet.GetDiff(); Assert.Equal(5, diffSet.GetSnapshot().Count); Assert.Equal(5, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 0; i < 5; i++) { Assert.True(diffSet.Contains(i)); Assert.True(diffPair.Added.Contains(i)); Assert.False(diffPair.Removed.Contains(i)); } }
public void DiffPairMatchesSnapshotAfterConcurrentChanges() { var random = new Random(); var diffSet = new DiffSet<int>(Enumerable.Range(0, 5)); var localSet = new HashSet<int>(Enumerable.Range(0, 5)); Action updateSet = () => { for (int i = 0; i < 100; i++) { if (random.Next(2) == 1) { diffSet.Remove(random.Next(5)); } else { diffSet.Add(random.Next(5)); } } }; // Flush initial changes var diffPair = diffSet.GetDiff(); Assert.Equal(5, diffPair.Added.Count); Assert.Equal(0, diffPair.Removed.Count); Assert.True(diffPair.Reset); for (int i = 0; i < 10; i++) { Task.WaitAll(Enumerable.Repeat(updateSet, 10).Select(Task.Factory.StartNew).ToArray()); var snapShot = diffSet.GetSnapshot(); diffPair = diffSet.GetDiff(); Assert.False(diffPair.Reset); Assert.Equal(0, diffPair.Added.Intersect(diffPair.Removed).Count()); foreach (var addedItem in diffPair.Added) { Assert.True(localSet.Add(addedItem)); } foreach (var removedItem in diffPair.Removed) { Assert.True(localSet.Remove(removedItem)); } int numSharedItems = localSet.Intersect(snapShot).Count(); Assert.Equal(numSharedItems, snapShot.Count); Assert.Equal(numSharedItems, localSet.Count); } }