mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Migrate devicelab to package:vm_service (#71882)
This commit is contained in:
parent
bff0ec470a
commit
9d1d0cfeb5
@ -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();
|
||||
class RunnerClient {
|
||||
const RunnerClient(this.client, this.isolate);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
// Make sure VM server is up by successfully opening and closing a socket.
|
||||
await (await WebSocket.connect(url)).close();
|
||||
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();
|
||||
|
||||
// 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));
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user