diff --git a/packages/flutter_tools/lib/src/commands/attach.dart b/packages/flutter_tools/lib/src/commands/attach.dart index 63e704890cda..288a02b1521d 100644 --- a/packages/flutter_tools/lib/src/commands/attach.dart +++ b/packages/flutter_tools/lib/src/commands/attach.dart @@ -428,6 +428,7 @@ known, it can be explicitly provided to attach via the command-line, e.g. final DebuggingOptions debuggingOptions = DebuggingOptions.enabled( buildInfo, enableDds: enableDds, + ddsPort: ddsPort, devToolsServerAddress: devToolsServerAddress, ); diff --git a/packages/flutter_tools/test/integration.shard/flutter_attach_test.dart b/packages/flutter_tools/test/integration.shard/flutter_attach_test.dart index 5cc8b560fbdd..a2621c4def64 100644 --- a/packages/flutter_tools/test/integration.shard/flutter_attach_test.dart +++ b/packages/flutter_tools/test/integration.shard/flutter_attach_test.dart @@ -3,6 +3,7 @@ // found in the LICENSE file. import 'package:file/file.dart'; +import 'package:flutter_tools/src/base/io.dart'; import 'package:vm_service/vm_service.dart'; import '../src/common.dart'; @@ -10,97 +11,150 @@ import 'test_data/basic_project.dart'; import 'test_driver.dart'; import 'test_utils.dart'; +Future getFreePort() async { + int port = 0; + final ServerSocket serverSocket = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0); + port = serverSocket.port; + await serverSocket.close(); + return port; +} + void main() { - late FlutterRunTestDriver flutterRun, flutterAttach; final BasicProject project = BasicProject(); late Directory tempDir; setUp(() async { tempDir = createResolvedTempDirectorySync('attach_test.'); await project.setUpIn(tempDir); - flutterRun = FlutterRunTestDriver(tempDir, logPrefix: ' RUN '); - flutterAttach = FlutterRunTestDriver( - tempDir, - logPrefix: 'ATTACH ', - // Only one DDS instance can be connected to the VM service at a time. - // DDS can also only initialize if the VM service doesn't have any existing - // clients, so we'll just let _flutterRun be responsible for spawning DDS. - spawnDdsInstance: false, - ); }); - tearDown(() async { - await flutterAttach.detach(); - await flutterRun.stop(); + tearDown(() { tryToDelete(tempDir); }); - testWithoutContext('can hot reload', () async { - await flutterRun.run(withDebugger: true); - await flutterAttach.attach(flutterRun.vmServicePort!); - await flutterAttach.hotReload(); - }); + group('DDS in flutter run', () { + late FlutterRunTestDriver flutterRun, flutterAttach; + setUp(() { + flutterRun = FlutterRunTestDriver(tempDir, logPrefix: ' RUN '); + flutterAttach = FlutterRunTestDriver( + tempDir, + logPrefix: 'ATTACH ', + // Only one DDS instance can be connected to the VM service at a time. + // DDS can also only initialize if the VM service doesn't have any existing + // clients, so we'll just let _flutterRun be responsible for spawning DDS. + spawnDdsInstance: false, + ); + }); - testWithoutContext('can detach, reattach, hot reload', () async { - await flutterRun.run(withDebugger: true); - await flutterAttach.attach(flutterRun.vmServicePort!); - await flutterAttach.detach(); - await flutterAttach.attach(flutterRun.vmServicePort!); - await flutterAttach.hotReload(); - }); + tearDown(() async { + await flutterAttach.detach(); + await flutterRun.stop(); + }); + + testWithoutContext('can hot reload', () async { + await flutterRun.run(withDebugger: true); + await flutterAttach.attach(flutterRun.vmServicePort!); + await flutterAttach.hotReload(); + }); + + testWithoutContext('can detach, reattach, hot reload', () async { + await flutterRun.run(withDebugger: true); + await flutterAttach.attach(flutterRun.vmServicePort!); + await flutterAttach.detach(); + await flutterAttach.attach(flutterRun.vmServicePort!); + await flutterAttach.hotReload(); + }); + + testWithoutContext('killing process behaves the same as detach ', () async { + await flutterRun.run(withDebugger: true); + await flutterAttach.attach(flutterRun.vmServicePort!); + await flutterAttach.quit(); + flutterAttach = FlutterRunTestDriver( + tempDir, + logPrefix: 'ATTACH-2', + spawnDdsInstance: false, + ); + await flutterAttach.attach(flutterRun.vmServicePort!); + await flutterAttach.hotReload(); + }); - testWithoutContext('killing process behaves the same as detach ', () async { - await flutterRun.run(withDebugger: true); - await flutterAttach.attach(flutterRun.vmServicePort!); - await flutterAttach.quit(); - flutterAttach = FlutterRunTestDriver( - tempDir, - logPrefix: 'ATTACH-2', - spawnDdsInstance: false, - ); - await flutterAttach.attach(flutterRun.vmServicePort!); - await flutterAttach.hotReload(); + testWithoutContext('sets activeDevToolsServerAddress extension', () async { + await flutterRun.run( + startPaused: true, + withDebugger: true, + additionalCommandArgs: ['--devtools-server-address', 'http://127.0.0.1:9105'], + ); + await flutterRun.resume(); + await pollForServiceExtensionValue( + testDriver: flutterRun, + extension: 'ext.flutter.activeDevToolsServerAddress', + continuePollingValue: '', + matches: equals('http://127.0.0.1:9105'), + ); + await pollForServiceExtensionValue( + testDriver: flutterRun, + extension: 'ext.flutter.connectedVmServiceUri', + continuePollingValue: '', + matches: isNotEmpty, + ); + + final Response response = await flutterRun.callServiceExtension('ext.flutter.connectedVmServiceUri'); + final String vmServiceUri = response.json!['value'] as String; + + // Attach with a different DevTools server address. + await flutterAttach.attach( + flutterRun.vmServicePort!, + additionalCommandArgs: ['--devtools-server-address', 'http://127.0.0.1:9110'], + ); + await pollForServiceExtensionValue( + testDriver: flutterAttach, + extension: 'ext.flutter.activeDevToolsServerAddress', + continuePollingValue: '', + matches: equals('http://127.0.0.1:9110'), + ); + await pollForServiceExtensionValue( + testDriver: flutterRun, + extension: 'ext.flutter.connectedVmServiceUri', + continuePollingValue: '', + matches: equals(vmServiceUri), + ); + }); }); - testWithoutContext('sets activeDevToolsServerAddress extension', () async { - await flutterRun.run( - startPaused: true, - withDebugger: true, - additionalCommandArgs: ['--devtools-server-address', 'http://127.0.0.1:9105'], - ); - await flutterRun.resume(); - await pollForServiceExtensionValue( - testDriver: flutterRun, - extension: 'ext.flutter.activeDevToolsServerAddress', - continuePollingValue: '', - matches: equals('http://127.0.0.1:9105'), - ); - await pollForServiceExtensionValue( - testDriver: flutterRun, - extension: 'ext.flutter.connectedVmServiceUri', - continuePollingValue: '', - matches: isNotEmpty, - ); - - final Response response = await flutterRun.callServiceExtension('ext.flutter.connectedVmServiceUri'); - final String vmServiceUri = response.json!['value'] as String; - - // Attach with a different DevTools server address. - await flutterAttach.attach( - flutterRun.vmServicePort!, - additionalCommandArgs: ['--devtools-server-address', 'http://127.0.0.1:9110'], - ); - await pollForServiceExtensionValue( - testDriver: flutterAttach, - extension: 'ext.flutter.activeDevToolsServerAddress', - continuePollingValue: '', - matches: equals('http://127.0.0.1:9110'), - ); - await pollForServiceExtensionValue( - testDriver: flutterRun, - extension: 'ext.flutter.connectedVmServiceUri', - continuePollingValue: '', - matches: equals(vmServiceUri), - ); + group('DDS in flutter attach', () { + late FlutterRunTestDriver flutterRun, flutterAttach; + setUp(() { + flutterRun = FlutterRunTestDriver( + tempDir, + logPrefix: ' RUN ', + spawnDdsInstance: false, + ); + flutterAttach = FlutterRunTestDriver( + tempDir, + logPrefix: 'ATTACH ', + ); + }); + + tearDown(() async { + await flutterAttach.detach(); + await flutterRun.stop(); + }); + + testWithoutContext('uses the designated dds port', () async { + final int ddsPort = await getFreePort(); + + await flutterRun.run(withDebugger: true); + await flutterAttach.attach( + flutterRun.vmServicePort!, + additionalCommandArgs: [ + '--dds-port=$ddsPort', + ], + ); + + final Response response = await flutterAttach.callServiceExtension('ext.flutter.connectedVmServiceUri'); + final String vmServiceUriString = response.json!['value'] as String; + final Uri vmServiceUri = Uri.parse(vmServiceUriString); + expect(vmServiceUri.port, equals(ddsPort)); + }); }); }