Unverified Commit 9d1d0cfe authored by Dan Field's avatar Dan Field Committed by GitHub

Migrate devicelab to package:vm_service (#71882)

parent bff0ec47
......@@ -37,7 +37,6 @@ dependencies:
image: 2.1.19 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
io: 0.3.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
js: 0.6.3-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
json_rpc_2: 2.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
logging: 0.11.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
matcher: 0.12.10-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
mime: 0.9.7 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
......@@ -63,7 +62,6 @@ dependencies:
test_core: 0.3.12-nullsafety.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 5.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service_client: 0.2.6+2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 0.9.7+15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 0.7.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
......@@ -74,4 +72,4 @@ dev_dependencies:
mockito: 4.1.1
test_api: 0.2.19-nullsafety.6
# PUBSPEC CHECKSUM: 2d0d
# PUBSPEC CHECKSUM: c008
......@@ -11,7 +11,8 @@ import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/task_result.dart';
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:path/path.dart' as path;
import 'package:vm_service_client/vm_service_client.dart';
import 'package:vm_service/vm_service.dart' as vms;
import 'package:vm_service/vm_service_io.dart' show vmServiceConnectUri;
void main() {
task(() async {
......@@ -54,52 +55,47 @@ void main() {
if (!ok)
throw 'Failed to run test app.';
final VMServiceClient client = VMServiceClient.connect('ws://localhost:$vmServicePort/ws');
final VM vm = await client.getVM();
final VMIsolateRef isolate = vm.isolates.first;
final vms.VmService client = await vmServiceConnectUri('ws://localhost:$vmServicePort/ws');
final vms.VM vm = await client.getVM();
final vms.IsolateRef isolate = vm.isolates.first;
final StreamController<VMExtensionEvent> frameEventsController = StreamController<VMExtensionEvent>();
final StreamController<VMExtensionEvent> navigationEventsController = StreamController<VMExtensionEvent>();
isolate.onExtensionEvent.listen((VMExtensionEvent event) {
if (event.kind == 'Flutter.Frame') {
frameEventsController.add(event);
} else if (event.kind == 'Flutter.Navigation') {
navigationEventsController.add(event);
final Completer<vms.Event> frameEventCompleter = Completer<vms.Event>();
final Completer<vms.Event> navigationEventCompleter = Completer<vms.Event>();
await client.streamListen(vms.EventStreams.kExtension);
client.onExtensionEvent.listen((vms.Event event) {
if (event.extensionKind == 'Flutter.Frame' && !frameEventCompleter.isCompleted) {
frameEventCompleter.complete(event);
} else if (event.extensionKind == 'Flutter.Navigation' && !navigationEventCompleter.isCompleted) {
navigationEventCompleter.complete(event);
}
});
final Stream<VMExtensionEvent> frameEvents = frameEventsController.stream;
final Stream<VMExtensionEvent> navigationEvents = navigationEventsController.stream;
print('reassembling app...');
final Future<VMExtensionEvent> frameFuture = frameEvents.first;
await isolate.invokeExtension('ext.flutter.reassemble');
await client.callServiceExtension('ext.flutter.reassemble', isolateId: isolate.id);
// ensure we get an event
final VMExtensionEvent event = await frameFuture;
print('${event.kind}: ${event.data}');
final vms.Event event = await frameEventCompleter.future;
print('${event.extensionKind}: ${event.extensionData.data}');
// validate the fields
// {number: 8, startTime: 0, elapsed: 1437, build: 600, raster: 800}
expect(event.data['number'] is int);
expect((event.data['number'] as int) >= 0);
expect(event.data['startTime'] is int);
expect((event.data['startTime'] as int) >= 0);
expect(event.data['elapsed'] is int);
expect((event.data['elapsed'] as int) >= 0);
expect(event.data['build'] is int);
expect((event.data['build'] as int) >= 0);
expect(event.data['raster'] is int);
expect((event.data['raster'] as int) >= 0);
expect(event.extensionData.data['number'] is int);
expect((event.extensionData.data['number'] as int) >= 0);
expect(event.extensionData.data['startTime'] is int);
expect((event.extensionData.data['startTime'] as int) >= 0);
expect(event.extensionData.data['elapsed'] is int);
expect((event.extensionData.data['elapsed'] as int) >= 0);
expect(event.extensionData.data['build'] is int);
expect((event.extensionData.data['build'] as int) >= 0);
expect(event.extensionData.data['raster'] is int);
expect((event.extensionData.data['raster'] as int) >= 0);
final Future<VMExtensionEvent> navigationFuture = navigationEvents.first;
// This tap triggers a navigation event.
device.tap(100, 200);
final VMExtensionEvent navigationEvent = await navigationFuture;
final vms.Event navigationEvent = await navigationEventCompleter.future;
// validate the fields
expect(navigationEvent.data['route'] is Map<dynamic, dynamic>);
final Map<dynamic, dynamic> route = navigationEvent.data['route'] as Map<dynamic, dynamic>;
expect(navigationEvent.extensionData.data['route'] is Map<dynamic, dynamic>);
final Map<dynamic, dynamic> route = navigationEvent.extensionData.data['route'] as Map<dynamic, dynamic>;
expect(route['description'] is String);
expect(route['settings'] is Map<dynamic, dynamic>);
final Map<dynamic, dynamic> settings = route['settings'] as Map<dynamic, dynamic>;
......
......@@ -69,7 +69,7 @@ class _TaskRunner {
});
registerExtension('ext.cocoonRunnerReady',
(String method, Map<String, String> parameters) async {
return ServiceExtensionResponse.result('"ready"');
return ServiceExtensionResponse.result('{"result":"ready"}');
});
}
......
......@@ -6,7 +6,8 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:vm_service_client/vm_service_client.dart';
import 'package:vm_service/vm_service.dart' as vms;
import 'package:vm_service/vm_service_io.dart';
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:flutter_devicelab/framework/adb.dart';
......@@ -79,10 +80,10 @@ Future<TaskResult> runTask(
});
try {
final VMIsolateRef isolate = await _connectToRunnerIsolate(await uri.future);
final Map<String, dynamic> taskResultJson = await isolate.invokeExtension('ext.cocoonRunTask') as Map<String, dynamic>;
final TaskResult taskResult = TaskResult.fromJson(taskResultJson);
final RunnerClient client = await RunnerClient.connect(await uri.future);
final TaskResult taskResult = await client.getTaskResult();
await runner.exitCode;
client.dispose();
return taskResult;
} finally {
if (!runnerFinished)
......@@ -92,33 +93,62 @@ Future<TaskResult> runTask(
}
}
Future<VMIsolateRef> _connectToRunnerIsolate(Uri vmServiceUri) async {
final List<String> pathSegments = <String>[
// Add authentication code.
if (vmServiceUri.pathSegments.isNotEmpty) vmServiceUri.pathSegments[0],
'ws',
];
final String url = vmServiceUri.replace(scheme: 'ws', pathSegments:
pathSegments).toString();
final Stopwatch stopwatch = Stopwatch()..start();
while (true) {
try {
// Make sure VM server is up by successfully opening and closing a socket.
await (await WebSocket.connect(url)).close();
// Look up the isolate.
final VMServiceClient client = VMServiceClient.connect(url);
final VM vm = await client.getVM();
final VMIsolateRef isolate = vm.isolates.single;
final String response = await isolate.invokeExtension('ext.cocoonRunnerReady') as String;
if (response != 'ready')
throw 'not ready yet';
return isolate;
} catch (error) {
if (stopwatch.elapsed > const Duration(seconds: 10))
print('VM service still not ready after ${stopwatch.elapsed}: $error\nContinuing to retry...');
await Future<void>.delayed(const Duration(milliseconds: 50));
class RunnerClient {
const RunnerClient(this.client, this.isolate);
static Future<RunnerClient> connect(Uri vmServiceUri) async {
final List<String> pathSegments = <String>[
// Add authentication code.
if (vmServiceUri.pathSegments.isNotEmpty) vmServiceUri.pathSegments[0],
'ws',
];
final String uri = vmServiceUri.replace(
scheme: 'ws',
pathSegments: pathSegments,
).toString();
final Stopwatch stopwatch = Stopwatch()..start();
while (true) {
try {
// Make sure VM server is up by successfully opening and closing a socket.
await (await WebSocket.connect(uri)).close();
final vms.VmService client = await vmServiceConnectUri(uri);
final vms.VM vm = await client.getVM();
final vms.IsolateRef isolate = vm.isolates.single;
final RunnerClient runnerClient = RunnerClient(client, isolate);
if (!await runnerClient.ready()) {
throw 'not ready yet';
}
return runnerClient;
} catch (error) {
if (stopwatch.elapsed > const Duration(seconds: 10)) {
print('VM service still not ready after ${stopwatch.elapsed}: $error\nContinuing to retry...');
}
await Future<void>.delayed(const Duration(milliseconds: 50));
}
}
}
final vms.VmService client;
final vms.IsolateRef isolate;
Future<bool> ready() async {
final vms.Response response = await _callServiceExtension('ext.cocoonRunnerReady');
return response.json['result'] == 'ready';
}
Future<TaskResult> getTaskResult() async {
final vms.Response taskResultResponse = await _callServiceExtension('ext.cocoonRunTask');
return TaskResult.fromJson(taskResultResponse.json);
}
Future<vms.Response> _callServiceExtension(String name) {
return client.callServiceExtension(name, isolateId: isolate.id);
}
void dispose() {
client.dispose();
}
}
......@@ -12,32 +12,26 @@ dependencies:
file: 6.0.0-nullsafety.4
http: 0.12.2
image: 2.1.19
logging: 0.11.4
meta: 1.3.0-nullsafety.6
path: 1.8.0-nullsafety.3
platform: 3.0.0-nullsafety.4
process: 4.0.0-nullsafety.4
stack_trace: 1.10.0-nullsafety.6
vm_service_client: 0.2.6+2
logging: 0.11.4
vm_service: 5.5.0
archive: 2.0.13 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.5.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
charcode: 1.2.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
collection: 1.15.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
convert: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
crypto: 2.1.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
http_parser: 3.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
json_rpc_2: 2.2.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pedantic: 1.10.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
petitparser: 3.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pub_semver: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.8.0-nullsafety.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
stream_channel: 2.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
typed_data: 1.3.0-nullsafety.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
xml: 4.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dev_dependencies:
......@@ -46,6 +40,7 @@ dev_dependencies:
_fe_analyzer_shared: 12.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
analyzer: 0.40.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
async: 2.5.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
cli_util: 0.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
coverage: 0.14.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
......@@ -60,17 +55,19 @@ dev_dependencies:
node_preamble: 1.4.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
package_config: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pool: 1.5.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pub_semver: 1.4.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf: 0.7.5 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf_packages_handler: 2.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf_static: 0.2.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf_web_socket: 0.2.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_map_stack_trace: 2.1.0-nullsafety.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.10-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
stream_channel: 2.1.0-nullsafety.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
test_api: 0.2.19-nullsafety.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
test_core: 0.3.12-nullsafety.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service: 5.5.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
watcher: 0.9.7+15 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
webkit_inspection_protocol: 0.7.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
yaml: 2.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 8dc5
# PUBSPEC CHECKSUM: c4c0
......@@ -94,7 +94,6 @@ executables:
stack_trace: 1.9.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
stream_channel: 1.6.8 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.0.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
vm_service_client: 0.2.6 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
web_socket_channel: 1.0.9 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
# PUBSPEC CHECKSUM: 29b9
......@@ -26,7 +26,6 @@ const Map<String, String> _kManuallyPinnedDependencies = <String, String>{
// existing tests do not fail when the package has a new version.
'flutter_gallery_assets': '^0.2.0',
'mockito': '4.1.1', // Prevent mockito from upgrading to the source gen version.
'vm_service_client': '0.2.6+2', // Final version before being marked deprecated.
'flutter_template_images': '1.0.1', // Must always exactly match flutter_tools template.
'shelf': '0.7.5',
// Dart team owned nnbd deps
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment