diff --git a/analysis_options.yaml b/analysis_options.yaml index ddd52e0f683a3..1fcc487181828 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -16,6 +16,7 @@ analyzer: deprecated_member_use: ignore deprecated_member_use_from_same_package: ignore exclude: # DIFFERENT FROM FLUTTER/FLUTTER + - examples # Fixture depends on dart:ui and raises false positives. - flutter_frontend_server/test/fixtures/lib/main.dart - prebuilts diff --git a/runtime/fixtures/dart_tool/flutter_build/dart_plugin_registrant.dart b/runtime/fixtures/dart_tool/flutter_build/dart_plugin_registrant.dart index 11beca884b1ee..71075630145fc 100644 --- a/runtime/fixtures/dart_tool/flutter_build/dart_plugin_registrant.dart +++ b/runtime/fixtures/dart_tool/flutter_build/dart_plugin_registrant.dart @@ -4,7 +4,6 @@ import 'dart:isolate'; import 'dart:ui'; -import 'dart:io' show Platform; @pragma('vm:external-name', 'PassMessage') external void passMessage(String message); @@ -14,18 +13,15 @@ bool didCallRegistrantBeforeEntrypoint = false; // Test the Dart plugin registrant. @pragma('vm:entry-point') class _PluginRegistrant { - @pragma('vm:entry-point') static void register() { if (didCallRegistrantBeforeEntrypoint) { - throw '_registerPlugins is being called twice'; + throw StateError('_registerPlugins is being called twice'); } didCallRegistrantBeforeEntrypoint = true; } - } - @pragma('vm:entry-point') void mainForPluginRegistrantTest() { if (didCallRegistrantBeforeEntrypoint) { @@ -42,22 +38,29 @@ void dartPluginRegistrantIsolate(SendPort sendPort) { sendPort.send(didCallRegistrantBeforeEntrypoint); } -void registerBackgroundIsolate(List args) { - SendPort sendPort = args[0] as SendPort; - RootIsolateToken token = args[1] as RootIsolateToken; +void registerBackgroundIsolate(List args) { + final sendPort = args[0]! as SendPort; + final token = args[1]! as RootIsolateToken; PlatformDispatcher.instance.registerBackgroundIsolate(token); sendPort.send(didCallRegistrantBeforeEntrypoint); } @pragma('vm:entry-point') -void callDartPluginRegistrantFromBackgroundIsolate() async { - ReceivePort receivePort = ReceivePort(); - Isolate isolate = await Isolate.spawn(dartPluginRegistrantIsolate, receivePort.sendPort); - bool didCallEntrypoint = await receivePort.first; +Future callDartPluginRegistrantFromBackgroundIsolate() async { + final receivePort = ReceivePort(); + final isolate = await Isolate.spawn( + dartPluginRegistrantIsolate, + receivePort.sendPort, + ); + final didCallEntrypoint = await receivePort.first as bool; if (didCallEntrypoint) { - passMessage('_PluginRegistrant.register() was called on background isolate'); + passMessage( + '_PluginRegistrant.register() was called on background isolate', + ); } else { - passMessage('_PluginRegistrant.register() was not called on background isolate'); + passMessage( + '_PluginRegistrant.register() was not called on background isolate', + ); } isolate.kill(); } @@ -67,27 +70,41 @@ void noDartPluginRegistrantIsolate(SendPort sendPort) { } @pragma('vm:entry-point') -void dontCallDartPluginRegistrantFromBackgroundIsolate() async { - ReceivePort receivePort = ReceivePort(); - Isolate isolate = await Isolate.spawn(noDartPluginRegistrantIsolate, receivePort.sendPort); - bool didCallEntrypoint = await receivePort.first; +Future dontCallDartPluginRegistrantFromBackgroundIsolate() async { + final receivePort = ReceivePort(); + final isolate = await Isolate.spawn( + noDartPluginRegistrantIsolate, + receivePort.sendPort, + ); + final didCallEntrypoint = await receivePort.first as bool; if (didCallEntrypoint) { - passMessage('_PluginRegistrant.register() was called on background isolate'); + passMessage( + '_PluginRegistrant.register() was called on background isolate', + ); } else { - passMessage('_PluginRegistrant.register() was not called on background isolate'); + passMessage( + '_PluginRegistrant.register() was not called on background isolate', + ); } isolate.kill(); } @pragma('vm:entry-point') -void registerBackgroundIsolateCallsDartPluginRegistrant() async { - ReceivePort receivePort = ReceivePort(); - Isolate isolate = await Isolate.spawn(registerBackgroundIsolate, [receivePort.sendPort, RootIsolateToken.instance]); - bool didCallEntrypoint = await receivePort.first; +Future registerBackgroundIsolateCallsDartPluginRegistrant() async { + final receivePort = ReceivePort(); + final isolate = await Isolate.spawn(registerBackgroundIsolate, [ + receivePort.sendPort, + RootIsolateToken.instance, + ]); + final didCallEntrypoint = await receivePort.first as bool; if (didCallEntrypoint) { - passMessage('_PluginRegistrant.register() was called on background isolate'); + passMessage( + '_PluginRegistrant.register() was called on background isolate', + ); } else { - passMessage('_PluginRegistrant.register() was not called on background isolate'); + passMessage( + '_PluginRegistrant.register() was not called on background isolate', + ); } isolate.kill(); } diff --git a/runtime/fixtures/runtime_test.dart b/runtime/fixtures/runtime_test.dart index 416902a815186..435c00430a1af 100644 --- a/runtime/fixtures/runtime_test.dart +++ b/runtime/fixtures/runtime_test.dart @@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// ignore_for_file: avoid_print + import 'dart:async'; import 'dart:isolate'; -import 'dart:ui'; import 'split_lib_test.dart' deferred as splitlib; @@ -17,30 +18,28 @@ void sayHi() { @pragma('vm:entry-point') void throwExceptionNow() { - throw 'Hello'; + throw AssertionError('Hello'); } @pragma('vm:entry-point') -void canRegisterNativeCallback() async { +Future canRegisterNativeCallback() async { print('In function canRegisterNativeCallback'); notifyNative(); print('Called native method from canRegisterNativeCallback'); } -Future? splitLoadFuture = null; +Future? splitLoadFuture; @pragma('vm:entry-point') void canCallDeferredLibrary() { print('In function canCallDeferredLibrary'); - splitLoadFuture = splitlib.loadLibrary() - .then((_) { - print('Deferred load complete'); - notifySuccess(splitlib.splitAdd(10, 23) == 33); - }) - .catchError((_) { - print('Deferred load error'); - notifySuccess(false); - }); + splitLoadFuture = splitlib.loadLibrary().then((_) { + print('Deferred load complete'); + notifySuccess(splitlib.splitAdd(10, 23) == 33); + }).catchError((_) { + print('Deferred load error'); + notifySuccess(false); + }); notifyNative(); } @@ -48,7 +47,7 @@ void canCallDeferredLibrary() { external void notifyNative(); @pragma('vm:entry-point') -void testIsolateShutdown() { } +void testIsolateShutdown() {} @pragma('vm:external-name', 'NotifyNative') external void notifyResult(bool success); @@ -56,44 +55,47 @@ external void notifyResult(bool success); external void passMessage(String message); void secondaryIsolateMain(String message) { - print('Secondary isolate got message: ' + message); + print('Secondary isolate got message: $message'); passMessage('Hello from code is secondary isolate.'); notifyNative(); } @pragma('vm:entry-point') void testCanLaunchSecondaryIsolate() { - final onExit = RawReceivePort((_) { notifyNative(); }); - Isolate.spawn(secondaryIsolateMain, 'Hello from root isolate.', onExit: onExit.sendPort); + final onExit = RawReceivePort((_) { + notifyNative(); + }); + Isolate.spawn(secondaryIsolateMain, 'Hello from root isolate.', + onExit: onExit.sendPort); } - @pragma('vm:entry-point') -void testIsolateStartupFailure() async { - Future mainTest(dynamic _) async { - Future testSuccessfullIsolateLaunch() async { +Future testIsolateStartupFailure() async { + Future mainTest(void _) async { + Future testSuccessfullIsolateLaunch() async { final onMessage = ReceivePort(); final onExit = ReceivePort(); final messages = StreamIterator(onMessage); final exits = StreamIterator(onExit); - await Isolate.spawn((SendPort port) => port.send('good'), - onMessage.sendPort, onExit: onExit.sendPort); + await Isolate.spawn( + (SendPort port) => port.send('good'), onMessage.sendPort, + onExit: onExit.sendPort); if (!await messages.moveNext()) { - throw 'Failed to receive message'; + throw AssertionError('Failed to receive message'); } if (messages.current != 'good') { - throw 'Failed to receive correct message'; + throw AssertionError('Failed to receive correct message'); } if (!await exits.moveNext()) { - throw 'Failed to receive onExit'; + throw AssertionError('Failed to receive onExit'); } messages.cancel(); exits.cancel(); } - Future testUnsuccessfullIsolateLaunch() async { + Future testUnsuccessfullIsolateLaunch() async { IsolateSpawnException? error; try { await Isolate.spawn((_) {}, null); @@ -101,7 +103,7 @@ void testIsolateStartupFailure() async { error = e; } if (error == null) { - throw 'Expected isolate spawn to fail.'; + throw AssertionError('Expected isolate spawn to fail.'); } } @@ -115,6 +117,7 @@ void testIsolateStartupFailure() async { // test in an isolate. Isolate.spawn(mainTest, null); } + @pragma('vm:external-name', 'MakeNextIsolateSpawnFail') external void makeNextIsolateSpawnFail(); @@ -132,35 +135,35 @@ void trampoline() { external void notifySuccess(bool success); @pragma('vm:entry-point') -void testCanConvertEmptyList(List args){ - notifySuccess(args.length == 0); +void testCanConvertEmptyList(List args) { + notifySuccess(args.isEmpty); } @pragma('vm:entry-point') -void testCanConvertListOfStrings(List args){ +void testCanConvertListOfStrings(List args) { notifySuccess(args.length == 4 && - args[0] == 'tinker' && - args[1] == 'tailor' && - args[2] == 'soldier' && - args[3] == 'sailor'); + args[0] == 'tinker' && + args[1] == 'tailor' && + args[2] == 'soldier' && + args[3] == 'sailor'); } @pragma('vm:entry-point') -void testCanConvertListOfDoubles(List args){ +void testCanConvertListOfDoubles(List args) { notifySuccess(args.length == 4 && - args[0] == 1.0 && - args[1] == 2.0 && - args[2] == 3.0 && - args[3] == 4.0); + args[0] == 1.0 && + args[1] == 2.0 && + args[2] == 3.0 && + args[3] == 4.0); } @pragma('vm:entry-point') -void testCanConvertListOfInts(List args){ +void testCanConvertListOfInts(List args) { notifySuccess(args.length == 4 && - args[0] == 1 && - args[1] == 2 && - args[2] == 3 && - args[3] == 4); + args[0] == 1 && + args[1] == 2 && + args[2] == 3 && + args[3] == 4); } bool didCallRegistrantBeforeEntrypoint = false; @@ -168,18 +171,15 @@ bool didCallRegistrantBeforeEntrypoint = false; // Test the Dart plugin registrant. @pragma('vm:entry-point') class _PluginRegistrant { - @pragma('vm:entry-point') static void register() { if (didCallRegistrantBeforeEntrypoint) { - throw '_registerPlugins is being called twice'; + throw AssertionError('_registerPlugins is being called twice'); } didCallRegistrantBeforeEntrypoint = true; } - } - @pragma('vm:entry-point') void mainForPluginRegistrantTest() { if (didCallRegistrantBeforeEntrypoint) { @@ -195,19 +195,19 @@ void mainForPlatformIsolates() { } @pragma('vm:entry-point') -void emptyMain(args) {} +void emptyMain(List args) {} @pragma('vm:entry-point') Function createEntryPointForPlatIsoSendAndRecvTest() { final port = RawReceivePort(); - port.handler = (message) { + port.handler = (Object? message) { port.close(); - (message as SendPort).send('Hello from root isolate!'); + (message! as SendPort).send('Hello from root isolate!'); }; final SendPort sendPort = port.sendPort; return () { final replyPort = RawReceivePort(); - replyPort.handler = (message) { + replyPort.handler = (Object? message) { replyPort.close(); passMessage('Platform isolate received: $message'); }; @@ -217,5 +217,5 @@ Function createEntryPointForPlatIsoSendAndRecvTest() { @pragma('vm:entry-point') void mainForPlatformIsolatesThrowError() { - throw 'Error from platform isolate'; + throw AssertionError('Error from platform isolate'); } diff --git a/shell/testing/observatory/launcher.dart b/shell/testing/observatory/launcher.dart index 0b4e91e3a5140..ee734c87d7973 100644 --- a/shell/testing/observatory/launcher.dart +++ b/shell/testing/observatory/launcher.dart @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// ignore_for_file: avoid_print + import 'dart:async'; import 'dart:convert'; import 'dart:io'; class ShellProcess { - final Completer _vmServiceUriCompleter = Completer(); - final Process _process; - ShellProcess(this._process) { // Scan stdout and scrape the VM Service Uri. _process.stdout @@ -23,6 +22,9 @@ class ShellProcess { }); } + final _vmServiceUriCompleter = Completer(); + final Process _process; + Future kill() async { return _process.kill(); } @@ -44,6 +46,16 @@ class ShellProcess { } class ShellLauncher { + ShellLauncher( + this.shellExecutablePath, + this.mainDartPath, + this.startPaused, + List extraArgs, + ) { + args.addAll(extraArgs); + args.add(mainDartPath); + } + final List args = [ '--vm-service-port=0', '--non-interactive', @@ -54,12 +66,6 @@ class ShellLauncher { final String mainDartPath; final bool startPaused; - ShellLauncher(this.shellExecutablePath, this.mainDartPath, this.startPaused, - List extraArgs) { - args.addAll(extraArgs); - args.add(mainDartPath); - } - Future launch() async { try { final List shellArguments = []; @@ -68,8 +74,10 @@ class ShellLauncher { } shellArguments.addAll(args); print('Launching $shellExecutablePath $shellArguments'); - final Process process = - await Process.start(shellExecutablePath, shellArguments); + final Process process = await Process.start( + shellExecutablePath, + shellArguments, + ); return ShellProcess(process); } catch (e) { print('Error launching shell: $e'); diff --git a/shell/testing/observatory/service_client.dart b/shell/testing/observatory/service_client.dart index 8d52c6ef1ca27..f9d74e31d4d0a 100644 --- a/shell/testing/observatory/service_client.dart +++ b/shell/testing/observatory/service_client.dart @@ -2,15 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +// ignore_for_file: avoid_print + import 'dart:async'; import 'dart:convert'; import 'dart:io'; class ServiceClient { - Completer? isolateStartedId; - Completer? isolatePausedId; - Completer? isolateResumeId; - ServiceClient( this.client, { this.isolateStartedId, @@ -20,18 +18,23 @@ class ServiceClient { client.listen(_onData, onError: _onError, cancelOnError: true); } - Future> invokeRPC(String method, - [Map? params]) async { + Completer? isolateStartedId; + Completer? isolatePausedId; + Completer? isolateResumeId; + + Future> invokeRPC( + String method, [ + Map? params, + ]) async { final String key = _createKey(); - final String request = json.encode({ + final String request = json.encode({ 'jsonrpc': '2.0', 'method': method, - 'params': params == null ? {} : params, + 'params': params ?? {}, 'id': key, }); client.add(request); - final Completer> completer = - Completer>(); + final completer = Completer>(); _outstandingRequests[key] = completer; print('-> $key ($method)'); return completer.future; @@ -44,55 +47,46 @@ class ServiceClient { } void _onData(dynamic message) { - final Map response = - json.decode(message as String) as Map; + final response = json.decode(message as String) as Map; 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']; + final completer = _outstandingRequests.remove(key)!; + final result = response['result']; + final error = response['error']; if (error != null) { - assert(result == null); completer.completeError(error); } else { - assert(result != null); completer.complete(result); } } else { if (response['method'] == 'streamNotify') { - _onServiceEvent(response['params'] as Map?); + _onServiceEvent(response['params'] as Map?); } } } - void _onServiceEvent(Map? params) { + void _onServiceEvent(Map? params) { if (params == null) { return; } - final Map? event = - params['event'] as Map?; + final event = params['event'] as Map?; if (event == null || event['type'] != 'Event') { return; } - final dynamic isolateId = event['isolate']['id']; + final dynamic isolateId = (event['isolate']! as Map)['id']; switch (params['streamId']) { case 'Isolate': if (event['kind'] == 'IsolateStart') { isolateStartedId?.complete(isolateId); } - break; case 'Debug': switch (event['kind']) { case 'Resume': isolateResumeId?.complete(isolateId); - break; case 'PauseStart': isolatePausedId?.complete(isolateId); - break; } - break; } } @@ -101,7 +95,6 @@ class ServiceClient { } final WebSocket client; - final Map> _outstandingRequests = - >{}; + final _outstandingRequests = >{}; int _id = 1; } diff --git a/shell/testing/observatory/test.dart b/shell/testing/observatory/test.dart index ad944dfb74210..2262769ff9880 100644 --- a/shell/testing/observatory/test.dart +++ b/shell/testing/observatory/test.dart @@ -4,6 +4,8 @@ // This is a minimal dependency heart beat test for the Dart VM Service. +// ignore_for_file: avoid_print + import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -12,37 +14,9 @@ import 'launcher.dart'; import 'service_client.dart'; class Expect { - static void equals(dynamic actual, dynamic expected) { + static void equals(Object? actual, Object? expected) { if (actual != expected) { - throw 'Expected $actual == $expected'; - } - } - - static void contains(String needle, String haystack) { - if (!haystack.contains(needle)) { - throw 'Expected $haystack to contain $needle'; - } - } - - static void isTrue(bool tf) { - if (tf != true) { - throw 'Expected $tf to be true'; - } - } - - static void isFalse(bool tf) { - if (tf != false) { - throw 'Expected $tf to be false'; - } - } - - static void notExecuted() { - throw 'Should not have hit'; - } - - static void isNotNull(dynamic a) { - if (a == null) { - throw 'Expected $a to not be null'; + throw AssertionError('Expected $actual == $expected'); } } } @@ -57,20 +31,20 @@ Future readResponse(HttpClientResponse response) { } // Test accessing the service protocol over http. -Future testHttpProtocolRequest(Uri uri) async { +Future testHttpProtocolRequest(Uri uri) async { uri = uri.replace(path: 'getVM'); final HttpClient client = HttpClient(); final HttpClientRequest request = await client.getUrl(uri); final HttpClientResponse response = await request.close(); Expect.equals(response.statusCode, 200); - final Map responseAsMap = - json.decode(await readResponse(response)) as Map; + final responseAsMap = + json.decode(await readResponse(response)) as Map; Expect.equals(responseAsMap['jsonrpc'], '2.0'); client.close(); } // Test accessing the service protocol over ws. -Future testWebSocketProtocolRequest(Uri uri) async { +Future testWebSocketProtocolRequest(Uri uri) async { uri = uri.replace(scheme: 'ws', path: 'ws'); final WebSocket webSocketClient = await WebSocket.connect(uri.toString()); final ServiceClient serviceClient = ServiceClient(webSocketClient); @@ -78,7 +52,7 @@ Future testWebSocketProtocolRequest(Uri uri) async { Expect.equals(response['type'], 'VM'); try { await serviceClient.invokeRPC('BART_SIMPSON'); - Expect.notExecuted(); + throw AssertionError('Unreachable'); } catch (e) { // Method not found. Expect.equals((e as Map)['code'], -32601); @@ -86,73 +60,17 @@ Future testWebSocketProtocolRequest(Uri uri) async { } // Test accessing an Observatory UI asset. -Future testHttpAssetRequest(Uri uri) async { +Future testHttpAssetRequest(Uri uri) async { uri = uri.replace(path: 'third_party/trace_viewer_full.html'); final HttpClient client = HttpClient(); final HttpClientRequest request = await client.getUrl(uri); final HttpClientResponse response = await request.close(); Expect.equals(response.statusCode, 200); - await response.drain(); + await response.drain(); client.close(); } -Future testStartPaused(Uri uri) async { - uri = uri.replace(scheme: 'ws', path: 'ws'); - final WebSocket webSocketClient = await WebSocket.connect(uri.toString()); - final Completer isolateStartedId = Completer(); - final Completer isolatePausedId = Completer(); - final Completer isolateResumeId = Completer(); - final ServiceClient serviceClient = ServiceClient(webSocketClient, - isolateStartedId: isolateStartedId, - isolatePausedId: isolatePausedId, - isolateResumeId: isolateResumeId); - await serviceClient - .invokeRPC('streamListen', {'streamId': 'Isolate'}); - await serviceClient - .invokeRPC('streamListen', {'streamId': 'Debug'}); - - final Map response = await serviceClient.invokeRPC('getVM'); - Expect.equals(response['type'], 'VM'); - String isolateId; - final List isolates = response['isolates'] as List; - if (isolates.isNotEmpty) { - isolateId = (isolates[0] as Map)['id']!; - } else { - // Wait until isolate starts. - isolateId = await isolateStartedId.future as String; - } - - // Grab the isolate. - Map isolate = - await serviceClient.invokeRPC('getIsolate', { - 'isolateId': isolateId, - }); - Expect.equals(isolate['type'], 'Isolate'); - Expect.isNotNull(isolate['pauseEvent']); - // If it is not runnable, wait until it becomes runnable. - if (isolate['pauseEvent']['kind'] == 'None') { - await isolatePausedId.future; - isolate = await serviceClient.invokeRPC('getIsolate', { - 'isolateId': isolateId, - }); - } - // Verify that it is paused at start. - Expect.equals(isolate['pauseEvent']['kind'], 'PauseStart'); - - // Resume the isolate. - await serviceClient.invokeRPC('resume', { - 'isolateId': isolateId, - }); - // Wait until the isolate has resumed. - await isolateResumeId.future; - final Map resumedResponse = await serviceClient - .invokeRPC('getIsolate', {'isolateId': isolateId}); - Expect.equals(resumedResponse['type'], 'Isolate'); - Expect.isNotNull(resumedResponse['pauseEvent']); - Expect.equals(resumedResponse['pauseEvent']['kind'], 'Resume'); -} - -typedef TestFunction = Future Function(Uri uri); +typedef TestFunction = Future Function(Uri uri); final List basicTests = [ testHttpProtocolRequest, @@ -160,11 +78,6 @@ final List basicTests = [ testHttpAssetRequest ]; -final List startPausedTests = [ - // TODO(engine): Investigate difference in lifecycle events. - // testStartPaused, -]; - Future runTests(ShellLauncher launcher, List tests) async { final ShellProcess? process = await launcher.launch(); if (process == null) { @@ -184,7 +97,7 @@ Future runTests(ShellLauncher launcher, List tests) async { return exitCode == 0; } -Future main(List args) async { +Future main(List args) async { if (args.length < 2) { print('Usage: dart ${Platform.script} ' ' ...'); @@ -198,9 +111,5 @@ Future main(List args) async { final ShellLauncher launcher = ShellLauncher(shellExecutablePath, mainDartPath, false, extraArgs); - final ShellLauncher startPausedlauncher = - ShellLauncher(shellExecutablePath, mainDartPath, true, extraArgs); - await runTests(launcher, basicTests); - await runTests(startPausedlauncher, startPausedTests); }