public void DepthSingleLinked([ValuesExcept(RecorderMode.Validation)] RecorderMode mode) { // This test verifies that we can serialize and/or read an extremely deep structure without blowing the stack. // We use single links so we don't generate refs, we actually embed objects. const int depth = 10_000; Dec.Config.TestParameters = new Dec.Config.UnitTestParameters { }; var parser = new Dec.Parser(); parser.Finish(); var root = new DoubleLinkedRecorder(); { var current = root; for (int i = 1; i < depth; ++i) { var next = new DoubleLinkedRecorder(); current.a = next; current = next; } } var deserialized = DoRecorderRoundTrip(root, mode, testSerializedResult: serialized => { // This verifies we haven't done an n^2 monstrosity by letting the depth get too far. // With 10_000 items, this generates a 300_000_000 byte file before depth controlling! Assert.Less(serialized.Length, 2_000_000); }); { var seen = new HashSet <DoubleLinkedRecorder>(); var current = deserialized; while (current != null && !seen.Contains(current)) { seen.Add(current); current = current.a; } Assert.AreEqual(depth, seen.Count); } }
public void DepthDoubleLinked([ValuesExcept(RecorderMode.Validation)] RecorderMode mode) { // This test verifies that we can write an extremely deep structure without blowing the stack. // We use double links so we don't have to worry about generating an absurd xml file in the process. // As of this writing, *without* the stack compensation code, 1000 works and 2000 doesn't // I'm choosing 10000 because it's well into the Doesn't Work territory, but it also doesn't take forever to run. const int depth = 10000; Dec.Config.TestParameters = new Dec.Config.UnitTestParameters { }; var parser = new Dec.Parser(); parser.Finish(); var root = new DoubleLinkedRecorder(); { var current = root; for (int i = 1; i < depth; ++i) { var next = new DoubleLinkedRecorder(); current.a = next; current.b = next; current = next; } } var deserialized = DoRecorderRoundTrip(root, mode); { var seen = new HashSet <DoubleLinkedRecorder>(); var current = deserialized; while (current != null && !seen.Contains(current)) { Assert.AreEqual(current.a, current.b); seen.Add(current); current = current.a; } Assert.AreEqual(depth, seen.Count); } }