blob: 4d120861f5eb5763f386be9155924ce6d4579505 [file] [log] [blame]
// Copyright (c) 2021, 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 'dart:developer';
import 'package:test/test.dart';
import 'package:vm_service/vm_service.dart';
import 'common/service_test_common.dart';
import 'common/test_helper.dart';
class Foo {
Foo() {
print('Foo');
}
}
class Bar {
Bar() {
print('Bar');
}
}
void test() {
debugger();
// Toggled on for Foo.
debugger();
debugger();
// Traced allocation.
Foo();
// Untraced allocation.
Bar();
// Toggled on for Bar.
debugger();
debugger();
// Traced allocation.
Bar();
debugger();
}
Future<Class?> getClassFromRootLib(
VmService service,
IsolateRef isolateRef,
String className,
) async {
final isolate = await service.getIsolate(isolateRef.id!);
Library rootLib =
(await service.getObject(isolate.id!, isolate.rootLib!.id!)) as Library;
for (ClassRef cls in rootLib.classes!) {
if (cls.name == className) {
return (await service.getObject(isolate.id!, cls.id!)) as Class;
}
}
return null;
}
final tests = <IsolateTest>[
hasStoppedAtBreakpoint,
// Initial.
(VmService service, IsolateRef isolate) async {
// Verify initial state of 'Foo'.
Class fooClass = (await getClassFromRootLib(service, isolate, 'Foo'))!;
expect(fooClass.name, equals('Foo'));
expect(fooClass.traceAllocations, false);
await service.setTraceClassAllocation(isolate.id!, fooClass.id!, true);
fooClass = await service.getObject(isolate.id!, fooClass.id!) as Class;
expect(fooClass.traceAllocations, true);
},
resumeIsolate,
hasStoppedAtBreakpoint,
// Extra debugger stop, continue to allow the allocation stubs to be switched
// over. This is a bug but low priority.
resumeIsolate,
hasStoppedAtBreakpoint,
// Allocation profile.
(VmService service, IsolateRef isolate) async {
Class fooClass = (await getClassFromRootLib(service, isolate, 'Foo'))!;
expect(fooClass.traceAllocations, true);
final profileResponse = await service.getAllocationTraces(isolate.id!);
expect(profileResponse, isNotNull);
expect(profileResponse.samples!.length, 1);
expect(profileResponse.samples!.first.identityHashCode != 0, true);
final instances = await service.getInstances(
isolate.id!,
fooClass.id!,
1,
);
expect(instances.totalCount, 1);
final instance = instances.instances!.first as InstanceRef;
expect(instance.identityHashCode != 0, isTrue);
expect(instance.identityHashCode,
profileResponse.samples!.first.identityHashCode);
await service.setTraceClassAllocation(isolate.id!, fooClass.id!, false);
fooClass = await service.getObject(isolate.id!, fooClass.id!) as Class;
expect(fooClass.traceAllocations, false);
},
resumeIsolate,
hasStoppedAtBreakpoint,
(VmService service, IsolateRef isolate) async {
// Trace Bar.
Class barClass = (await getClassFromRootLib(service, isolate, 'Bar'))!;
expect(barClass.traceAllocations, false);
await service.setTraceClassAllocation(isolate.id!, barClass.id!, true);
barClass = (await getClassFromRootLib(service, isolate, 'Bar'))!;
expect(barClass.traceAllocations, true);
},
resumeIsolate,
hasStoppedAtBreakpoint,
// Extra debugger stop, continue to allow the allocation stubs to be switched
// over. This is a bug but low priority.
resumeIsolate,
hasStoppedAtBreakpoint,
(VmService service, IsolateRef isolate) async {
// Ensure the allocation of `Bar()` was recorded.
final profileResponse = (await service.getAllocationTraces(isolate.id!));
expect(profileResponse.samples!.length, 2);
},
];
main(args) async => runIsolateTests(
args,
tests,
"get_allocation_traces_test.dart",
testeeConcurrent: test,
);