Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion shell/testing/observatory/empty_main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

main() {
void main() {
}
19 changes: 9 additions & 10 deletions shell/testing/observatory/launcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,23 @@ import 'dart:convert';
import 'dart:io';

class ShellProcess {
final Completer _observatoryUriCompleter = new Completer();
final Completer<Uri> _observatoryUriCompleter = new Completer<Uri>();
final Process _process;

ShellProcess(this._process) {
assert(_process != null);
ShellProcess(this._process) : assert(_process != null) {
// Scan stdout and scrape the Observatory Uri.
_process.stdout.transform(UTF8.decoder)
.transform(new LineSplitter()).listen((line) {
_process.stdout.transform(utf8.decoder)
.transform(const LineSplitter()).listen((String line) {
const String observatoryUriPrefix = 'Observatory listening on ';
if (line.startsWith(observatoryUriPrefix)) {
print(line);
Uri uri = Uri.parse(line.substring(observatoryUriPrefix.length));
final Uri uri = Uri.parse(line.substring(observatoryUriPrefix.length));
_observatoryUriCompleter.complete(uri);
}
});
}

Future kill() async {
Future<bool> kill() async {
if (_process == null) {
return false;
}
Expand All @@ -39,7 +38,7 @@ class ShellProcess {
}

class ShellLauncher {
final List<String> args = [
final List<String> args = <String>[
'--observatory-port=0',
'--non-interactive',
'--run-forever',
Expand All @@ -60,13 +59,13 @@ class ShellLauncher {

Future<ShellProcess> launch() async {
try {
List<String> shellArguments = [];
final List<String> shellArguments = <String>[];
if (startPaused) {
shellArguments.add('--start-paused');
}
shellArguments.addAll(args);
print('Launching $shellExecutablePath $shellArguments');
var process = await Process.start(shellExecutablePath, shellArguments);
final Process process = await Process.start(shellExecutablePath, shellArguments);
return new ShellProcess(process);
} catch (e) {
print('Error launching shell: $e');
Expand Down
90 changes: 65 additions & 25 deletions shell/testing/observatory/service_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,100 @@

library observatory_sky_shell_service_client;


import 'dart:async';
import 'dart:convert';
import 'dart:io';


class ServiceClient {
ServiceClient(this.client) {
Completer<dynamic> isolateStartedId;
Completer<dynamic> isolatePausedId;
Completer<dynamic> isolateResumeId;

ServiceClient(this.client, {this.isolateStartedId, this.isolatePausedId,
this.isolateResumeId}) {
client.listen(_onData,
onError: _onError,
cancelOnError: true);
}

Future<Map> invokeRPC(String method, [Map params]) async {
var key = _createKey();
var request = JSON.encode({
Future<Map<String, dynamic>> invokeRPC(String method, [Map<String, dynamic> params]) async {
final String key = _createKey();
final String request = json.encode(<String, dynamic>{
'jsonrpc': '2.0',
'method': method,
'params': params == null ? {} : params,
'params': params == null ? <String, dynamic>{} : params,
'id': key,
});
client.add(request);
var completer = new Completer();
_outstanding_requests[key] = completer;
final Completer<Map<String, dynamic>> completer = new Completer<Map<String, dynamic>>();
_outstandingRequests[key] = completer;
print('-> $key ($method)');
return completer.future;
}

String _createKey() {
var key = '$_id';
final String key = '$_id';
_id++;
return key;
}

void _onData(String message) {
var response = JSON.decode(message);
var key = response['id'];
print('<- $key');
var completer = _outstanding_requests.remove(key);
assert(completer != null);
var result = response['result'];
var error = response['error'];
if (error != null) {
assert(result == null);
completer.completeError(error);
void _onData(dynamic message) {
final Map<String, dynamic> response = json.decode(message);
final dynamic key = response['id'];
if (key != null) {
print('<- $key');
final dynamic completer = _outstandingRequests.remove(key);
assert(completer != null);
final dynamic result = response['result'];
final dynamic error = response['error'];
if (error != null) {
assert(result == null);
completer.completeError(error);
} else {
assert(result != null);
completer.complete(result);
}
} else {
assert(result != null);
completer.complete(result);
if (response['method'] == 'streamNotify') {
_onServiceEvent(response['params']);
}
}
}

void _onServiceEvent(Map<String, dynamic> params) {
if (params == null) {
return;
}
final Map<String, dynamic> event = params['event'];
if (event == null || event['type'] != 'Event') {
return;
}
final dynamic isolateId = event['isolate']['id'];
switch (params['streamId']) {
case 'Isolate':
if (event['kind'] == 'IsolateStarted') {
isolateStartedId?.complete(isolateId);
}
break;
case 'Debug':
switch (event['kind']) {
case 'Resume':
isolateResumeId?.complete(isolateId);
break;
case 'PauseStart':
isolatePausedId?.complete(isolateId);
break;
}
break;
}
}

void _onError(error) {
void _onError(dynamic error) {
print('WebSocket error: $error');
}

final WebSocket client;
final Map<String, Completer> _outstanding_requests = <String, Completer>{};
var _id = 1;
final Map<String, Completer<dynamic>> _outstandingRequests = <String, Completer<dynamic>>{};
int _id = 1;
}
Loading