| Index: runtime/observatory/tests/service/test_helper.dart
|
| diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
|
| index 6b37421fafc1b5938e0f8bae51989878fb29c06e..00978cafa169b7784cfd7ae76f5b98408a7e6747 100644
|
| --- a/runtime/observatory/tests/service/test_helper.dart
|
| +++ b/runtime/observatory/tests/service/test_helper.dart
|
| @@ -8,29 +8,88 @@ import 'dart:async';
|
| import 'dart:convert';
|
| import 'dart:io';
|
| import 'package:observatory/service_io.dart';
|
| -import 'package:unittest/unittest.dart';
|
| +import 'service_test_common.dart';
|
| +
|
| +/// Will be set to the http address of the VM's service protocol before
|
| +/// any tests are invoked.
|
| +String serviceHttpAddress;
|
| +String serviceWebsocketAddress;
|
|
|
| bool _isWebSocketDisconnect(e) {
|
| return e is NetworkRpcException;
|
| }
|
|
|
| -// This invocation should set up the state being tested.
|
| -const String _TESTEE_MODE_FLAG = "--testee-mode";
|
| +const String _TESTEE_ENV_KEY = 'SERVICE_TEST_TESTEE';
|
| +const Map<String, String> _TESTEE_SPAWN_ENV = const {
|
| + _TESTEE_ENV_KEY: 'true'
|
| +};
|
| +bool _isTestee() {
|
| + return Platform.environment.containsKey(_TESTEE_ENV_KEY);
|
| +}
|
| +
|
| +class _SerivceTesteeRunner {
|
| + Future run({Future testeeBefore(): null,
|
| + Future testeeConcurrent(): null,
|
| + bool pause_on_start: false,
|
| + bool pause_on_exit: false}) async {
|
| + if (!pause_on_start) {
|
| + if (testeeBefore != null) {
|
| + var result = testeeBefore();
|
| + if (result is Future) {
|
| + await result;
|
| + }
|
| + }
|
| + print(''); // Print blank line to signal that testeeBefore has run.
|
| + }
|
| + if (testeeConcurrent != null) {
|
| + var result = testeeConcurrent();
|
| + if (result is Future) {
|
| + await result;
|
| + }
|
| + }
|
| + if (!pause_on_exit) {
|
| + // Wait around for the process to be killed.
|
| + stdin.first.then((_) => exit(0));
|
| + }
|
| + }
|
| +
|
| + void runSync({void testeeBeforeSync(): null,
|
| + void testeeConcurrentSync(): null,
|
| + bool pause_on_start: false,
|
| + bool pause_on_exit: false}) {
|
| + if (!pause_on_start) {
|
| + if (testeeBeforeSync != null) {
|
| + testeeBeforeSync();
|
| + }
|
| + print(''); // Print blank line to signal that testeeBefore has run.
|
| + }
|
| + if (testeeConcurrentSync != null) {
|
| + testeeConcurrentSync();
|
| + }
|
| + if (!pause_on_exit) {
|
| + // Wait around for the process to be killed.
|
| + stdin.first.then((_) => exit(0));
|
| + }
|
| + }
|
| +}
|
|
|
| -class _TestLauncher {
|
| +class _ServiceTesteeLauncher {
|
| Process process;
|
| final List<String> args;
|
| bool killedByTester = false;
|
|
|
| - _TestLauncher() : args = ['--enable-vm-service:0',
|
| - Platform.script.toFilePath(),
|
| - _TESTEE_MODE_FLAG] {}
|
| + _ServiceTesteeLauncher() :
|
| + args = ['--enable-vm-service:0',
|
| + Platform.script.toFilePath()] {}
|
|
|
| - Future<int> launch(bool pause_on_start,
|
| - bool pause_on_exit,
|
| - bool pause_on_unhandled_exceptions,
|
| - bool trace_service,
|
| - bool trace_compiler) {
|
| + String get executablePath => Platform.executable;
|
| +
|
| + // Spawn the testee process.
|
| + Future<Process> _spawnProcess(bool pause_on_start,
|
| + bool pause_on_exit,
|
| + bool pause_on_unhandled_exceptions,
|
| + bool trace_service,
|
| + bool trace_compiler) {
|
| assert(pause_on_start != null);
|
| assert(pause_on_exit != null);
|
| assert(trace_service != null);
|
| @@ -58,8 +117,21 @@ class _TestLauncher {
|
| fullArgs.addAll(Platform.executableArguments);
|
| fullArgs.addAll(args);
|
| print('** Launching $dartExecutable ${fullArgs.join(' ')}');
|
| - return Process.start(dartExecutable, fullArgs).then((p) {
|
| + return Process.start(dartExecutable,
|
| + fullArgs,
|
| + environment: _TESTEE_SPAWN_ENV);
|
| + }
|
|
|
| + Future<int> launch(bool pause_on_start,
|
| + bool pause_on_exit,
|
| + bool pause_on_unhandled_exceptions,
|
| + bool trace_service,
|
| + bool trace_compiler) {
|
| + return _spawnProcess(pause_on_start,
|
| + pause_on_exit,
|
| + pause_on_unhandled_exceptions,
|
| + trace_service,
|
| + trace_compiler).then((p) {
|
| Completer completer = new Completer();
|
| process = p;
|
| var portNumber;
|
| @@ -106,67 +178,57 @@ class _TestLauncher {
|
| }
|
| }
|
|
|
| -typedef Future IsolateTest(Isolate isolate);
|
| -typedef Future VMTest(VM vm);
|
| -
|
| -/// Will be set to the http address of the VM's service protocol before
|
| -/// any tests are invoked.
|
| -String serviceHttpAddress;
|
| -
|
| -/// Runs [tests] in sequence, each of which should take an [Isolate] and
|
| -/// return a [Future]. Code for setting up state can run before and/or
|
| -/// concurrently with the tests. Uses [mainArgs] to determine whether
|
| -/// to run tests or testee in this invokation of the script.
|
| -Future runIsolateTests(List<String> mainArgs,
|
| - List<IsolateTest> tests,
|
| - {testeeBefore(),
|
| - void testeeConcurrent(),
|
| - bool pause_on_start: false,
|
| - bool pause_on_exit: false,
|
| - bool trace_service: false,
|
| - bool trace_compiler: false,
|
| - bool verbose_vm: false,
|
| - bool pause_on_unhandled_exceptions: false}) async {
|
| - assert(!pause_on_start || testeeBefore == null);
|
| - if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
|
| - if (!pause_on_start) {
|
| - if (testeeBefore != null) {
|
| - var result = testeeBefore();
|
| - if (result is Future) {
|
| - await result;
|
| - }
|
| - }
|
| - print(''); // Print blank line to signal that we are ready.
|
| - }
|
| - if (testeeConcurrent != null) {
|
| - testeeConcurrent();
|
| - }
|
| - if (!pause_on_exit) {
|
| - // Wait around for the process to be killed.
|
| - stdin.first.then((_) => exit(0));
|
| - }
|
| - } else {
|
| - var process = new _TestLauncher();
|
| +class _ServiceTesterRunner {
|
| + void run({List<String> mainArgs,
|
| + List<VMTest> vmTests,
|
| + List<IsolateTest> isolateTests,
|
| + bool pause_on_start: false,
|
| + bool pause_on_exit: false,
|
| + bool trace_service: false,
|
| + bool trace_compiler: false,
|
| + bool verbose_vm: false,
|
| + bool pause_on_unhandled_exceptions: false}) {
|
| + var process = new _ServiceTesteeLauncher();
|
| process.launch(pause_on_start, pause_on_exit,
|
| pause_on_unhandled_exceptions,
|
| - trace_service, trace_compiler).then((port) {
|
| + trace_service, trace_compiler).then((port) async {
|
| if (mainArgs.contains("--gdb")) {
|
| port = 8181;
|
| }
|
| - String addr = 'ws://localhost:$port/ws';
|
| + serviceWebsocketAddress = 'ws://localhost:$port/ws';
|
| serviceHttpAddress = 'http://localhost:$port';
|
| - var testIndex = 1;
|
| - var totalTests = tests.length;
|
| var name = Platform.script.pathSegments.last;
|
| runZoned(() {
|
| - new WebSocketVM(new WebSocketVMTarget(addr)).load()
|
| - .then((VM vm) => vm.isolates.first.load())
|
| - .then((Isolate isolate) => Future.forEach(tests, (test) {
|
| - isolate.vm.verbose = verbose_vm;
|
| - print('Running $name [$testIndex/$totalTests]');
|
| - testIndex++;
|
| - return test(isolate);
|
| - })).then((_) => process.requestExit());
|
| + new WebSocketVM(new WebSocketVMTarget(serviceWebsocketAddress)).load()
|
| + .then((VM vm) async {
|
| +
|
| + // Run vm tests.
|
| + if (vmTests != null) {
|
| + var testIndex = 1;
|
| + var totalTests = vmTests.length;
|
| + for (var test in vmTests) {
|
| + vm.verbose = verbose_vm;
|
| + print('Running $name [$testIndex/$totalTests]');
|
| + testIndex++;
|
| + await test(vm);
|
| + }
|
| + }
|
| +
|
| + // Run isolate tests.
|
| + if (isolateTests != null) {
|
| + var isolate = await vm.isolates.first.load();
|
| + var testIndex = 1;
|
| + var totalTests = isolateTests.length;
|
| + for (var test in isolateTests) {
|
| + vm.verbose = verbose_vm;
|
| + print('Running $name [$testIndex/$totalTests]');
|
| + testIndex++;
|
| + await test(isolate);
|
| + }
|
| + }
|
| +
|
| + await process.requestExit();
|
| + });
|
| }, onError: (e, st) {
|
| process.requestExit();
|
| if (!_isWebSocketDisconnect(e)) {
|
| @@ -182,14 +244,44 @@ Future runIsolateTests(List<String> mainArgs,
|
| /// return a [Future]. Code for setting up state can run before and/or
|
| /// concurrently with the tests. Uses [mainArgs] to determine whether
|
| /// to run tests or testee in this invokation of the script.
|
| +Future runIsolateTests(List<String> mainArgs,
|
| + List<IsolateTest> tests,
|
| + {testeeBefore(),
|
| + testeeConcurrent(),
|
| + bool pause_on_start: false,
|
| + bool pause_on_exit: false,
|
| + bool trace_service: false,
|
| + bool trace_compiler: false,
|
| + bool verbose_vm: false,
|
| + bool pause_on_unhandled_exceptions: false}) async {
|
| + assert(!pause_on_start || testeeBefore == null);
|
| + if (_isTestee()) {
|
| + new _SerivceTesteeRunner().run(testeeBefore: testeeBefore,
|
| + testeeConcurrent: testeeConcurrent,
|
| + pause_on_start: pause_on_start,
|
| + pause_on_exit: pause_on_exit);
|
| + } else {
|
| + new _ServiceTesterRunner().run(
|
| + mainArgs: mainArgs,
|
| + isolateTests: tests,
|
| + pause_on_start: pause_on_start,
|
| + pause_on_exit: pause_on_exit,
|
| + trace_service: trace_service,
|
| + trace_compiler: trace_compiler,
|
| + verbose_vm: verbose_vm,
|
| + pause_on_unhandled_exceptions: pause_on_unhandled_exceptions);
|
| + }
|
| +}
|
| +
|
| +/// Runs [tests] in sequence, each of which should take an [Isolate] and
|
| +/// return a [Future]. Code for setting up state can run before and/or
|
| +/// concurrently with the tests. Uses [mainArgs] to determine whether
|
| +/// to run tests or testee in this invokation of the script.
|
| ///
|
| /// This is a special version of this test harness specifically for the
|
| /// pause_on_unhandled_exceptions_test, which cannot properly function
|
| /// in an async context (because exceptions are *always* handled in async
|
| /// functions).
|
| -///
|
| -/// TODO(johnmccutchan): Don't use the shared harness for the
|
| -/// pause_on_unhandled_exceptions_test.
|
| void runIsolateTestsSynchronous(List<String> mainArgs,
|
| List<IsolateTest> tests,
|
| {void testeeBefore(),
|
| @@ -201,275 +293,22 @@ void runIsolateTestsSynchronous(List<String> mainArgs,
|
| bool verbose_vm: false,
|
| bool pause_on_unhandled_exceptions: false}) {
|
| assert(!pause_on_start || testeeBefore == null);
|
| - if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
|
| - if (!pause_on_start) {
|
| - if (testeeBefore != null) {
|
| - testeeBefore();
|
| - }
|
| - print(''); // Print blank line to signal that we are ready.
|
| - }
|
| - if (testeeConcurrent != null) {
|
| - testeeConcurrent();
|
| - }
|
| - if (!pause_on_exit) {
|
| - // Wait around for the process to be killed.
|
| - stdin.first.then((_) => exit(0));
|
| - }
|
| + if (_isTestee()) {
|
| + new _SerivceTesteeRunner().runSync(testeeBeforeSync: testeeBefore,
|
| + testeeConcurrentSync: testeeConcurrent,
|
| + pause_on_start: pause_on_start,
|
| + pause_on_exit: pause_on_exit);
|
| } else {
|
| - var process = new _TestLauncher();
|
| - process.launch(pause_on_start, pause_on_exit,
|
| - pause_on_unhandled_exceptions,
|
| - trace_service, trace_compiler).then((port) {
|
| - if (mainArgs.contains("--gdb")) {
|
| - port = 8181;
|
| - }
|
| - String addr = 'ws://localhost:$port/ws';
|
| - serviceHttpAddress = 'http://localhost:$port';
|
| - var testIndex = 1;
|
| - var totalTests = tests.length;
|
| - var name = Platform.script.pathSegments.last;
|
| - runZoned(() {
|
| - new WebSocketVM(new WebSocketVMTarget(addr)).load()
|
| - .then((VM vm) => vm.isolates.first.load())
|
| - .then((Isolate isolate) => Future.forEach(tests, (test) {
|
| - isolate.vm.verbose = verbose_vm;
|
| - print('Running $name [$testIndex/$totalTests]');
|
| - testIndex++;
|
| - return test(isolate);
|
| - })).then((_) => process.requestExit());
|
| - }, onError: (e, st) {
|
| - process.requestExit();
|
| - if (!_isWebSocketDisconnect(e)) {
|
| - print('Unexpected exception in service tests: $e $st');
|
| - throw e;
|
| - }
|
| - });
|
| - });
|
| - }
|
| -}
|
| -
|
| -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;
|
| + new _ServiceTesterRunner().run(
|
| + mainArgs: mainArgs,
|
| + isolateTests: tests,
|
| + pause_on_start: pause_on_start,
|
| + pause_on_exit: pause_on_exit,
|
| + trace_service: trace_service,
|
| + trace_compiler: trace_compiler,
|
| + verbose_vm: verbose_vm,
|
| + pause_on_unhandled_exceptions: pause_on_unhandled_exceptions);
|
| }
|
| -
|
| - 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;
|
| }
|
|
|
|
|
| @@ -479,57 +318,28 @@ Future<Instance> rootLibraryFieldValue(Isolate isolate,
|
| /// to run tests or testee in this invokation of the script.
|
| Future runVMTests(List<String> mainArgs,
|
| List<VMTest> tests,
|
| - {Future testeeBefore(),
|
| - Future testeeConcurrent(),
|
| + {testeeBefore(),
|
| + testeeConcurrent(),
|
| bool pause_on_start: false,
|
| bool pause_on_exit: false,
|
| bool trace_service: false,
|
| bool trace_compiler: false,
|
| bool verbose_vm: false,
|
| bool pause_on_unhandled_exceptions: false}) async {
|
| - if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
|
| - if (!pause_on_start) {
|
| - if (testeeBefore != null) {
|
| - await testeeBefore();
|
| - }
|
| - print(''); // Print blank line to signal that we are ready.
|
| - }
|
| - if (testeeConcurrent != null) {
|
| - await testeeConcurrent();
|
| - }
|
| - if (!pause_on_exit) {
|
| - // Wait around for the process to be killed.
|
| - stdin.first.then((_) => exit(0));
|
| - }
|
| + if (_isTestee()) {
|
| + new _SerivceTesteeRunner().run(testeeBefore: testeeBefore,
|
| + testeeConcurrent: testeeConcurrent,
|
| + pause_on_start: pause_on_start,
|
| + pause_on_exit: pause_on_exit);
|
| } else {
|
| - var process = new _TestLauncher();
|
| - process.launch(pause_on_start,
|
| - pause_on_exit,
|
| - pause_on_unhandled_exceptions,
|
| - trace_service, trace_compiler).then((port) async {
|
| - if (mainArgs.contains("--gdb")) {
|
| - port = 8181;
|
| - }
|
| - String addr = 'ws://localhost:$port/ws';
|
| - serviceHttpAddress = 'http://localhost:$port';
|
| - var testIndex = 1;
|
| - var totalTests = tests.length;
|
| - var name = Platform.script.pathSegments.last;
|
| - runZoned(() {
|
| - new WebSocketVM(new WebSocketVMTarget(addr)).load()
|
| - .then((VM vm) => Future.forEach(tests, (test) {
|
| - vm.verbose = verbose_vm;
|
| - print('Running $name [$testIndex/$totalTests]');
|
| - testIndex++;
|
| - return test(vm);
|
| - })).then((_) => process.requestExit());
|
| - }, onError: (e, st) {
|
| - process.requestExit();
|
| - if (!_isWebSocketDisconnect(e)) {
|
| - print('Unexpected exception in service tests: $e $st');
|
| - throw e;
|
| - }
|
| - });
|
| - });
|
| + new _ServiceTesterRunner().run(
|
| + mainArgs: mainArgs,
|
| + vmTests: tests,
|
| + pause_on_start: pause_on_start,
|
| + pause_on_exit: pause_on_exit,
|
| + trace_service: trace_service,
|
| + trace_compiler: trace_compiler,
|
| + verbose_vm: verbose_vm,
|
| + pause_on_unhandled_exceptions: pause_on_unhandled_exceptions);
|
| }
|
| }
|
|
|