Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(235)

Unified Diff: runtime/observatory/tests/service/service_test_common.dart

Issue 1726773002: Refactor service tests in preparation of running on sky_shell (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/observatory/tests/service/service_test_common.dart
diff --git a/runtime/observatory/tests/service/service_test_common.dart b/runtime/observatory/tests/service/service_test_common.dart
new file mode 100644
index 0000000000000000000000000000000000000000..7435ee5c0fde984d2fe2fcf26e60c26971a94b91
--- /dev/null
+++ b/runtime/observatory/tests/service/service_test_common.dart
@@ -0,0 +1,236 @@
+// Copyright (c) 2016, 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.
+
+library service_test_common;
+
+import 'dart:async';
+import 'package:observatory/service_common.dart';
+import 'package:unittest/unittest.dart';
+
+typedef Future IsolateTest(Isolate isolate);
+typedef Future VMTest(VM vm);
+
+Future asyncStepOver(Isolate isolate) async {
+ final Completer pausedAtSyntheticBreakpoint = new Completer();
+ StreamSubscription subscription;
+
+ // Cancel the subscription.
+ cancelSubscription() {
+ if (subscription != null) {
+ subscription.cancel();
+ subscription = null;
+ }
+ }
+
+ // Complete futures with with error.
+ completeError(error) {
+ if (!pausedAtSyntheticBreakpoint.isCompleted) {
+ pausedAtSyntheticBreakpoint.completeError(error);
+ }
+ }
+
+ // Subscribe to the debugger event stream.
+ Stream stream;
+ try {
+ stream = await isolate.vm.getEventStream(VM.kDebugStream);
+ } catch (e) {
+ completeError(e);
+ return pausedAtSyntheticBreakpoint.future;
+ }
+
+ Breakpoint syntheticBreakpoint;
+
+ subscription = stream.listen((ServiceEvent event) async {
+ // Synthetic breakpoint add event. This is the first event we will
+ // receive.
+ bool isAdd = (event.kind == ServiceEvent.kBreakpointAdded) &&
+ (event.breakpoint.isSyntheticAsyncContinuation) &&
+ (event.owner == isolate);
+ // Resume after synthetic breakpoint added. This is the second event
+ // we will recieve.
+ bool isResume = (event.kind == ServiceEvent.kResume) &&
+ (syntheticBreakpoint != null) &&
+ (event.owner == isolate);
+ // Paused at synthetic breakpoint. This is the third event we will
+ // receive.
+ bool isPaused = (event.kind == ServiceEvent.kPauseBreakpoint) &&
+ (syntheticBreakpoint != null) &&
+ (event.breakpoint == syntheticBreakpoint);
+ if (isAdd) {
+ syntheticBreakpoint = event.breakpoint;
+ } else if (isResume) {
+ } else if (isPaused) {
+ pausedAtSyntheticBreakpoint.complete(isolate);
+ syntheticBreakpoint = null;
+ cancelSubscription();
+ }
+ });
+
+ // Issue the step OverAwait command.
+ try {
+ await isolate.stepOverAsyncSuspension();
+ } catch (e) {
+ // This can fail when another client issued the same resume command
+ // or another client has moved the isolate forward.
+ cancelSubscription();
+ completeError(e);
+ }
+
+ return pausedAtSyntheticBreakpoint.future;
+}
+
+
+Future<Isolate> hasPausedFor(Isolate isolate, String kind) {
+ // Set up a listener to wait for breakpoint events.
+ Completer completer = new Completer();
+ isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
+ var subscription;
+ subscription = stream.listen((ServiceEvent event) {
+ if (event.kind == kind) {
+ print('Paused with $kind');
+ subscription.cancel();
+ if (completer != null) {
+ // Reload to update isolate.pauseEvent.
+ completer.complete(isolate.reload());
+ completer = null;
+ }
+ }
+ });
+
+ // Pause may have happened before we subscribed.
+ isolate.reload().then((_) {
+ if ((isolate.pauseEvent != null) &&
+ (isolate.pauseEvent.kind == kind)) {
+ // Already waiting at a breakpoint.
+ print('Paused with $kind');
+ subscription.cancel();
+ if (completer != null) {
+ completer.complete(isolate);
+ completer = null;
+ }
+ }
+ });
+ });
+
+ return completer.future; // Will complete when breakpoint hit.
+}
+
+Future<Isolate> hasStoppedAtBreakpoint(Isolate isolate) {
+ return hasPausedFor(isolate, ServiceEvent.kPauseBreakpoint);
+}
+
+Future<Isolate> hasStoppedWithUnhandledException(Isolate isolate) {
+ return hasPausedFor(isolate, ServiceEvent.kPauseException);
+}
+
+Future<Isolate> hasPausedAtStart(Isolate isolate) {
+ return hasPausedFor(isolate, ServiceEvent.kPauseStart);
+}
+
+// Currying is your friend.
+IsolateTest setBreakpointAtLine(int line) {
+ return (Isolate isolate) async {
+ print("Setting breakpoint for line $line");
+ Library lib = await isolate.rootLibrary.load();
+ Script script = lib.scripts.single;
+
+ Breakpoint bpt = await isolate.addBreakpoint(script, line);
+ print("Breakpoint is $bpt");
+ expect(bpt, isNotNull);
+ expect(bpt is Breakpoint, isTrue);
+ };
+}
+
+IsolateTest stoppedAtLine(int line) {
+ return (Isolate isolate) async {
+ print("Checking we are at line $line");
+
+ ServiceMap stack = await isolate.getStack();
+ expect(stack.type, equals('Stack'));
+
+ List<Frame> frames = stack['frames'];
+ expect(frames.length, greaterThanOrEqualTo(1));
+
+ Frame top = frames[0];
+ Script script = await top.location.script.load();
+ int actualLine = script.tokenToLine(top.location.tokenPos);
+ if (actualLine != line) {
+ var sb = new StringBuffer();
+ sb.write("Expected to be at line $line but actually at line $actualLine");
+ sb.write("\nFull stack trace:\n");
+ for (Frame f in stack['frames']) {
+ sb.write(" $f [${await f.location.getLine()}]\n");
+ }
+ throw sb.toString();
+ }
+ };
+}
+
+
+Future<Isolate> resumeIsolate(Isolate isolate) {
+ Completer completer = new Completer();
+ isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
+ var subscription;
+ subscription = stream.listen((ServiceEvent event) {
+ if (event.kind == ServiceEvent.kResume) {
+ subscription.cancel();
+ completer.complete();
+ }
+ });
+ });
+ isolate.resume();
+ return completer.future;
+}
+
+
+Future resumeAndAwaitEvent(Isolate isolate, stream, onEvent) async {
+ Completer completer = new Completer();
+ var sub;
+ sub = await isolate.vm.listenEventStream(
+ stream,
+ (ServiceEvent event) {
+ var r = onEvent(event);
+ if (r is! Future) {
+ r = new Future.value(r);
+ }
+ r.then((x) => sub.cancel().then((_) {
+ completer.complete();
+ }));
+ });
+ await isolate.resume();
+ return completer.future;
+}
+
+IsolateTest resumeIsolateAndAwaitEvent(stream, onEvent) {
+ return (Isolate isolate) async =>
+ resumeAndAwaitEvent(isolate, stream, onEvent);
+}
+
+
+Future<Isolate> stepOver(Isolate isolate) async {
+ await isolate.stepOver();
+ return hasStoppedAtBreakpoint(isolate);
+}
+
+Future<Class> getClassFromRootLib(Isolate isolate, String className) async {
+ Library rootLib = await isolate.rootLibrary.load();
+ for (var i = 0; i < rootLib.classes.length; i++) {
+ Class cls = rootLib.classes[i];
+ if (cls.name == className) {
+ return cls;
+ }
+ }
+ return null;
+}
+
+
+Future<Instance> rootLibraryFieldValue(Isolate isolate,
+ String fieldName) async {
+ Library rootLib = await isolate.rootLibrary.load();
+ Field field = rootLib.variables.singleWhere((v) => v.name == fieldName);
+ await field.load();
+ Instance value = field.staticValue;
+ await value.load();
+ return value;
+}

Powered by Google App Engine
This is Rietveld 408576698