blob: 09592fd27816203dc14a8f0ca03befb7ad1346ac [file] [log] [blame]
// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
import 'common/test_helper.dart';
class Foo {
dynamic left;
dynamic right;
}
late Foo r;
late List lst;
void script() {
// Create 3 instances of Foo, with out-degrees
// 0 (for b), 1 (for a), and 2 (for staticFoo).
r = Foo();
var a = Foo();
var b = Foo();
r.left = a;
r.right = b;
a.left = b;
lst = List.filled(2, null);
lst[0] = lst; // Self-loop.
// Larger than any other fixed-size list in a fresh heap.
lst[1] = List.filled(1234569, null);
}
var tests = <IsolateTest>[
(VmService service, IsolateRef isolate) async {
final snapshotGraph = await HeapSnapshotGraph.getSnapshot(service, isolate);
expect(snapshotGraph.name, "main");
expect(snapshotGraph.flags, isNotNull);
expect(snapshotGraph.objects, isNotNull);
expect(snapshotGraph.objects, isNotEmpty);
int actualShallowSize = 0;
int actualRefCount = 0;
snapshotGraph.objects.forEach((HeapSnapshotObject o) {
// -1 is the CID used by the sentinel.
expect(o.classId >= -1, isTrue);
expect(o.data, isNotNull);
expect(o.references, isNotNull);
actualShallowSize += o.shallowSize;
actualRefCount += o.references.length;
});
// Some accounting differences in the VM result in the global shallow size
// often being greater than the sum of the object shallow sizes.
expect(snapshotGraph.shallowSize >= actualShallowSize, isTrue);
expect(snapshotGraph.shallowSize <= snapshotGraph.capacity, isTrue);
expect(snapshotGraph.referenceCount >= actualRefCount, isTrue);
int actualExternalSize = 0;
expect(snapshotGraph.externalProperties, isNotEmpty);
snapshotGraph.externalProperties.forEach((HeapSnapshotExternalProperty e) {
actualExternalSize += e.externalSize;
expect(e.object >= 0, isTrue);
expect(e.name, isNotNull);
});
expect(snapshotGraph.externalSize, actualExternalSize);
expect(snapshotGraph.classes, isNotEmpty);
snapshotGraph.classes.forEach((HeapSnapshotClass c) {
expect(c.name, isNotNull);
expect(c.libraryName, isNotNull);
expect(c.libraryUri, isNotNull);
expect(c.fields, isNotNull);
});
// We have the class "Foo".
int foosFound = 0;
int fooClassId = -1;
for (int i = 0; i < snapshotGraph.classes.length; i++) {
HeapSnapshotClass c = snapshotGraph.classes[i];
if (c.name == "Foo" &&
c.libraryUri.toString().endsWith("heap_snapshot_graph_test.dart")) {
foosFound++;
fooClassId = i;
}
}
expect(foosFound, equals(1));
// It knows about "Foo" objects.
foosFound = 0;
snapshotGraph.objects.forEach((HeapSnapshotObject o) {
if (o.classId == 0) return;
if (o.classId == fooClassId) {
foosFound++;
}
});
expect(foosFound, equals(3));
// Check that we can get another snapshot.
final snapshotGraph2 =
await HeapSnapshotGraph.getSnapshot(service, isolate);
expect(snapshotGraph2.name, "main");
},
];
main([args = const <String>[]]) async => runIsolateTests(
args,
tests,
'heap_snapshot_graph_test.dart',
testeeBefore: script,
);