public async Task CanReadObjectArray() { using (var scope = await HeapAnalysisScope.Create()) { var array = scope.Subject.GetFieldValue <ClrArrayObject>("ObjectArray"); Assert.That(array.Length, Is.EqualTo(5)); var elements = array.AsEnumerable <IClrObject>().ToArray(); Assert.That(elements.Select(e => e?.GetType()), Is.EqualTo(new [] { typeof(ClrClassObject), typeof(ClrStructObject), null, typeof(ClrPrimitive), typeof(ClrPrimitive) })); Assert.That(Composite.ReadFrom(elements[0].CastAs <IClrCompositeObject>()), Is.EqualTo(new Composite { StringField = "ObjectArray.One", IntegerField = 10 })); Assert.That(Composite.ReadFrom(elements[1].CastAs <IClrCompositeObject>()), Is.EqualTo(new Composite { StringField = "ObjectArray.Two", IntegerField = 20 })); Assert.That(elements[2], Is.Null); Assert.That(elements[3].CastAs <int>(), Is.EqualTo(42)); Assert.That(elements[4].CastAs <string>(), Is.EqualTo("ObjectArray.String")); } }
public async Task CanReadNull() { using (var scope = await HeapAnalysisScope.Create()) { var value = scope.Subject.GetFieldValue <IClrObject>("NullObjectField"); Assert.That(value, Is.Null); } }
public async Task StructTypeIsNotARoot() { using (var scope = await HeapAnalysisScope.Create()) { var root = scope.Subject.OwningHeap.EnumerateRoots().FirstOrDefault(r => r.Type.CanBeAssignedTo <HeapAnalysisTarget.Program.StructType>()); Assert.That(root, Is.Null); } }
public async Task CanReadStringArray() { using (var scope = await HeapAnalysisScope.Create()) { var array = scope.Subject.GetFieldValue <ClrArrayObject>("StringArray"); Assert.That(array.AsEnumerable <string>(), Is.EqualTo(new [] { "A", "B", "C" })); } }
public async Task CanReadGuid() { using (var scope = await HeapAnalysisScope.Create()) { var value = scope.Subject.GetFieldValue <Guid>("Guid"); Assert.That(value, Is.EqualTo(new Guid("01234567-89AB-CDEF-0123-456789ABCDEF"))); } }
public async Task CanReadIntegerArray() { using (var scope = await HeapAnalysisScope.Create()) { var array = scope.Subject.GetFieldValue <ClrArrayObject>("IntegerArray"); Assert.That(array.AsEnumerable <int>(), Is.EqualTo(new [] { 1, 2, 3 })); } }
public async Task CanReadInteger() { using (var scope = await HeapAnalysisScope.Create()) { var value = scope.Subject.GetFieldValue <int>("IntegerField"); Assert.That(value, Is.EqualTo(42)); } }
public async Task CanReadIntPtr() { using (var scope = await HeapAnalysisScope.Create()) { var value = scope.Subject.GetFieldValue <IntPtr>("IntPtr"); Assert.That(value, Is.EqualTo(new IntPtr(0x0dedbeef))); } }
public async Task CanReadString() { using (var scope = await HeapAnalysisScope.Create()) { var value = scope.Subject.GetFieldValue <string>("StringField"); Assert.That(value, Is.EqualTo("StringField")); } }
public async Task IClrObjectWrapperTypeIsEqualToItself(string fieldName) { using (var scope = await HeapAnalysisScope.Create()) { var wrapper = scope.Subject.GetFieldValue <IClrObject>(fieldName); Assert.That(wrapper, Is.EqualTo(wrapper)); } }
public async Task CanInspectSecureDelegate() { using (var scope = await HeapAnalysisScope.Create()) { var delegateObj = scope.Subject.GetFieldValue(nameof(HeapAnalysisTarget.Program.SecureDelegate)).CastAs <IClrCompositeObject>(); var details = new DelegateInspector().Inspect(delegateObj); Assert.That(details.Kind.HasFlag(DelegateKind.Secure7)); } }
public async Task CanReadInteger() { using (var scope = await HeapAnalysisScope.Create()) { var value = scope.Subject.GetFieldValue <IClrObject>("IntegerAsObjectField"); Assert.That(value.Type.CanBeAssignedTo <int>()); Assert.That(value.CastAs <int>(), Is.EqualTo(42)); } }
public async Task CanReadClassType() { using (var scope = await HeapAnalysisScope.Create()) { var value = scope.Subject.GetFieldValue <ClrClassObject>("ClassTypeField"); Assert.That(value.Type.CanBeAssignedTo <HeapAnalysisTarget.Program.ClassType>()); Assert.That(value.GetFieldValue <string>("StringField"), Is.EqualTo("ClassTypeField.StringField")); Assert.That(value.GetFieldValue <int>("IntegerField"), Is.EqualTo(42)); } }
public async Task CanReadClassType() { using (var scope = await HeapAnalysisScope.Create()) { var root = scope.Subject.OwningHeap.EnumerateRoots().FirstOrDefault(r => r.Type.CanBeAssignedTo <HeapAnalysisTarget.Program.ClassType>()); var value = new ClrObjectReader().ReadGCRoot(root); var actual = value.CastAs <ClrClassObject>(); Assert.That(actual.GetFieldValue <string>("StringField"), Is.EqualTo("localClass")); Assert.That(actual.GetFieldValue <int>("IntegerField"), Is.EqualTo(42)); } }
public async Task CanInspectInstanceOpenVirtualDelegate() { using (var scope = await HeapAnalysisScope.Create()) { var delegateObj = scope.Subject.GetFieldValue(nameof(HeapAnalysisTarget.Program.InstanceOpenVirtualDelegate)).CastAs <IClrCompositeObject>(); var details = new DelegateInspector().Inspect(delegateObj); Assert.That(details.Kind.HasFlag(DelegateKind.InstanceOpenVirtual3)); Assert.That(details.TargetOrFirstArg, Is.Null); Assert.That(details.Method, Is.EqualTo(scope.FindClrType <HeapAnalysisTarget.Program.InstanceDelegateContainer>().FindMethodByName("VirtualMethod")).Using(new ClrMethodEqualityComparer())); } }
public async Task IClrObjectWrapperTypeIsNotEqualToAnother(string fieldA, string fieldB) { if (fieldA == fieldB) { return; // Handled by the other test. } using (var scope = await HeapAnalysisScope.Create()) { var wrapperA = scope.Subject.GetFieldValue <IClrObject>(fieldA); var wrapperB = scope.Subject.GetFieldValue <IClrObject>(fieldB); Assert.That(wrapperA, Is.Not.EqualTo(wrapperB)); } }
public async Task CanReadStructType() { using (var scope = await HeapAnalysisScope.Create()) { // Field type is Object, but the value is a boxed struct. We will get a ClrStructObject even // though, statically, the field should yield a ClrReferenceObject. var value = scope.Subject.GetFieldValue <IClrObject>("StructTypeAsObjectField"); Assert.That(value.Type.CanBeAssignedTo <HeapAnalysisTarget.Program.StructType>()); var actual = value.CastAs <ClrStructObject>(); Assert.That(actual.GetFieldValue <string>("StringField"), Is.EqualTo("StructTypeAsObjectField.StringField")); Assert.That(actual.GetFieldValue <int>("IntegerField"), Is.EqualTo(42)); } }
public async Task CanInspectInstanceClosedDelegate() { using (var scope = await HeapAnalysisScope.Create()) { var delegateObj = scope.Subject.GetFieldValue(nameof(HeapAnalysisTarget.Program.InstanceClosedDelegate)).CastAs <IClrCompositeObject>(); var details = new DelegateInspector().Inspect(delegateObj); Assert.That(details.Kind.HasFlag(DelegateKind.InstanceClosed1)); var targetInstance = details.TargetOrFirstArg.CastAs <ClrClassObject>(); Assert.That(targetInstance.Type.CanBeAssignedTo <HeapAnalysisTarget.Program.InstanceDelegateContainer>()); Assert.That(targetInstance.GetFieldValue <string>("instanceId"), Is.EqualTo("Instance1")); Assert.That(details.Method, Is.EqualTo(targetInstance.Type.FindMethodByName("Method")).Using(new ClrMethodEqualityComparer())); } }
public async Task CanReadStructArray() { using (var scope = await HeapAnalysisScope.Create()) { var array = scope.Subject.GetFieldValue <ClrArrayObject>("StructArray"); Assert.That(array.Length, Is.EqualTo(2)); var elements = array.AsEnumerable <ClrStructObject>().Select(Composite.ReadFrom); Assert.That(elements, Is.EqualTo(new [] { new Composite { StringField = "StructArray.One", IntegerField = 10 }, new Composite { StringField = "StructArray.Two", IntegerField = 20 } })); } }