| 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 63b8fc2bb97231c11cc4683971353398e2bed074..b498f4a0b8bc0c42a8e62a1391408f0910154bcd 100644
 | 
| --- a/runtime/observatory/tests/service/test_helper.dart
 | 
| +++ b/runtime/observatory/tests/service/test_helper.dart
 | 
| @@ -91,25 +91,29 @@ class _ServiceTesteeLauncher {
 | 
|                                  bool pause_on_exit,
 | 
|                                  bool pause_on_unhandled_exceptions,
 | 
|                                  bool trace_service,
 | 
| -                                bool trace_compiler) {
 | 
| +                                bool trace_compiler,
 | 
| +                                bool testeeControlsServer) {
 | 
|      assert(pause_on_start != null);
 | 
|      assert(pause_on_exit != null);
 | 
|      assert(pause_on_unhandled_exceptions != null);
 | 
|      assert(trace_service != null);
 | 
|      assert(trace_compiler != null);
 | 
| +    assert(testeeControlsServer != null);
 | 
|  
 | 
|      if (_shouldLaunchSkyShell()) {
 | 
|        return _spawnSkyProcess(pause_on_start,
 | 
|                                pause_on_exit,
 | 
|                                pause_on_unhandled_exceptions,
 | 
|                                trace_service,
 | 
| -                              trace_compiler);
 | 
| +                              trace_compiler,
 | 
| +                              testeeControlsServer);
 | 
|      } else {
 | 
|        return _spawnDartProcess(pause_on_start,
 | 
|                                 pause_on_exit,
 | 
|                                 pause_on_unhandled_exceptions,
 | 
|                                 trace_service,
 | 
| -                               trace_compiler);
 | 
| +                               trace_compiler,
 | 
| +                               testeeControlsServer);
 | 
|      }
 | 
|    }
 | 
|  
 | 
| @@ -117,7 +121,8 @@ class _ServiceTesteeLauncher {
 | 
|                                      bool pause_on_exit,
 | 
|                                      bool pause_on_unhandled_exceptions,
 | 
|                                      bool trace_service,
 | 
| -                                    bool trace_compiler) {
 | 
| +                                    bool trace_compiler,
 | 
| +                                    bool testeeControlsServer) {
 | 
|      assert(!_shouldLaunchSkyShell());
 | 
|  
 | 
|      String dartExecutable = Platform.executable;
 | 
| @@ -141,7 +146,9 @@ class _ServiceTesteeLauncher {
 | 
|      }
 | 
|  
 | 
|      fullArgs.addAll(Platform.executableArguments);
 | 
| -    fullArgs.add('--enable-vm-service:0');
 | 
| +    if (!testeeControlsServer) {
 | 
| +      fullArgs.add('--enable-vm-service:0');
 | 
| +    }
 | 
|      fullArgs.addAll(args);
 | 
|  
 | 
|      return _spawnCommon(dartExecutable, fullArgs);
 | 
| @@ -179,7 +186,9 @@ class _ServiceTesteeLauncher {
 | 
|      dartFlags.add('--enable_mirrors=true');
 | 
|  
 | 
|      fullArgs.addAll(Platform.executableArguments);
 | 
| -    fullArgs.add('--observatory-port=0');
 | 
| +    if (!testeeControlsServer) {
 | 
| +      fullArgs.add('--observatory-port=0');
 | 
| +    }
 | 
|      fullArgs.add('--dart-flags=${dartFlags.join(' ')}');
 | 
|      fullArgs.addAll(args);
 | 
|  
 | 
| @@ -194,37 +203,38 @@ class _ServiceTesteeLauncher {
 | 
|      return Process.start(executable, arguments, environment: environment);
 | 
|    }
 | 
|  
 | 
| -  Future<int> launch(bool pause_on_start,
 | 
| +  Future<Uri> launch(bool pause_on_start,
 | 
|                       bool pause_on_exit,
 | 
|                       bool pause_on_unhandled_exceptions,
 | 
|                       bool trace_service,
 | 
| -                     bool trace_compiler) {
 | 
| +                     bool trace_compiler,
 | 
| +                     bool testeeControlsServer) {
 | 
|      return _spawnProcess(pause_on_start,
 | 
|                    pause_on_exit,
 | 
|                    pause_on_unhandled_exceptions,
 | 
|                    trace_service,
 | 
| -                  trace_compiler).then((p) {
 | 
| -      Completer completer = new Completer();
 | 
| +                  trace_compiler,
 | 
| +                  testeeControlsServer).then((p) {
 | 
| +      Completer<Uri> completer = new Completer<Uri>();
 | 
|        process = p;
 | 
| -      var portNumber;
 | 
| +      Uri uri;
 | 
|        var blank;
 | 
|        var first = true;
 | 
|        process.stdout.transform(UTF8.decoder)
 | 
|                      .transform(new LineSplitter()).listen((line) {
 | 
| -        if (line.startsWith('Observatory listening on http://')) {
 | 
| -          RegExp portExp = new RegExp(r"\d+.\d+.\d+.\d+:(\d+)");
 | 
| -          var port = portExp.firstMatch(line).group(1);
 | 
| -          portNumber = int.parse(port);
 | 
| +        const kObservatoryListening = 'Observatory listening on ';
 | 
| +        if (line.startsWith(kObservatoryListening)) {
 | 
| +          uri = Uri.parse(line.substring(kObservatoryListening.length));
 | 
|          }
 | 
|          if (pause_on_start || line == '') {
 | 
|            // Received blank line.
 | 
|            blank = true;
 | 
|          }
 | 
| -        if (portNumber != null && blank == true && first == true) {
 | 
| -          completer.complete(portNumber);
 | 
| +        if ((uri != null) && (blank == true) && (first == true)) {
 | 
| +          completer.complete(uri);
 | 
|            // Stop repeat completions.
 | 
|            first = false;
 | 
| -          print('** Signaled to run test queries on $portNumber');
 | 
| +          print('** Signaled to run test queries on $uri');
 | 
|          }
 | 
|          print('>testee>out> $line');
 | 
|        });
 | 
| @@ -250,62 +260,11 @@ class _ServiceTesteeLauncher {
 | 
|    }
 | 
|  }
 | 
|  
 | 
| -// A tester runner that doesn't spawn a process but instead connects to
 | 
| -// an already running flutter application running on a device. Assumes
 | 
| -// port 8100. This is only useful for debugging.
 | 
| -class _FlutterDeviceServiceTesterRunner {
 | 
| -  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 port = 8100;
 | 
| -    serviceWebsocketAddress = 'ws://localhost:$port/ws';
 | 
| -    serviceHttpAddress = 'http://localhost:$port';
 | 
| -    var name = Platform.script.pathSegments.last;
 | 
| -    Chain.capture(() async {
 | 
| -      var vm =
 | 
| -          new WebSocketVM(new WebSocketVMTarget(serviceWebsocketAddress));
 | 
| -      print('Loading VM...');
 | 
| -      await vm.load();
 | 
| -      print('Done loading VM');
 | 
| -
 | 
| -      // 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);
 | 
| -        }
 | 
| -      }
 | 
| -    }, onError: (error, stackTrace) {
 | 
| -      print('Unexpected exception in service tests: $error\n$stackTrace');
 | 
| -    });
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -void suppressWarning() {
 | 
| -  new _FlutterDeviceServiceTesterRunner();
 | 
| +void setupAddresses(Uri serverAddress) {
 | 
| +  serviceWebsocketAddress =
 | 
| +          'ws://${serverAddress.authority}${serverAddress.path}ws';
 | 
| +  serviceHttpAddress =
 | 
| +      'http://${serverAddress.authority}${serverAddress.path}';
 | 
|  }
 | 
|  
 | 
|  class _ServiceTesterRunner {
 | 
| @@ -317,19 +276,20 @@ class _ServiceTesterRunner {
 | 
|              bool trace_service: false,
 | 
|              bool trace_compiler: false,
 | 
|              bool verbose_vm: false,
 | 
| -            bool pause_on_unhandled_exceptions: false}) {
 | 
| +            bool pause_on_unhandled_exceptions: false,
 | 
| +            bool testeeControlsServer: false}) {
 | 
|      var process = new _ServiceTesteeLauncher();
 | 
|      process.launch(pause_on_start, pause_on_exit,
 | 
|                     pause_on_unhandled_exceptions,
 | 
| -                   trace_service, trace_compiler).then((port) async {
 | 
| +                   trace_service, trace_compiler,
 | 
| +                   testeeControlsServer).then((Uri serverAddress) async {
 | 
|        if (mainArgs.contains("--gdb")) {
 | 
|          var pid = process.process.pid;
 | 
|          var wait = new Duration(seconds: 10);
 | 
|          print("Testee has pid $pid, waiting $wait before continuing");
 | 
|          sleep(wait);
 | 
|        }
 | 
| -      serviceWebsocketAddress = 'ws://localhost:$port/ws';
 | 
| -      serviceHttpAddress = 'http://localhost:$port';
 | 
| +      setupAddresses(serverAddress);
 | 
|        var name = Platform.script.pathSegments.last;
 | 
|        Chain.capture(() async {
 | 
|          var vm =
 | 
| @@ -386,7 +346,8 @@ Future runIsolateTests(List<String> mainArgs,
 | 
|                          bool trace_service: false,
 | 
|                          bool trace_compiler: false,
 | 
|                          bool verbose_vm: false,
 | 
| -                        bool pause_on_unhandled_exceptions: false}) async {
 | 
| +                        bool pause_on_unhandled_exceptions: false,
 | 
| +                        bool testeeControlsServer: false}) async {
 | 
|    assert(!pause_on_start || testeeBefore == null);
 | 
|    if (_isTestee()) {
 | 
|      new _ServiceTesteeRunner().run(testeeBefore: testeeBefore,
 | 
| @@ -402,7 +363,8 @@ Future runIsolateTests(List<String> mainArgs,
 | 
|          trace_service: trace_service,
 | 
|          trace_compiler: trace_compiler,
 | 
|          verbose_vm: verbose_vm,
 | 
| -        pause_on_unhandled_exceptions: pause_on_unhandled_exceptions);
 | 
| +        pause_on_unhandled_exceptions: pause_on_unhandled_exceptions,
 | 
| +        testeeControlsServer: testeeControlsServer);
 | 
|    }
 | 
|  }
 | 
|  
 | 
| 
 |