Unverified Commit f6bedddd authored by Ben Konyi's avatar Ben Konyi Committed by GitHub

Support legacy behavior for --host-vmservice-port and --observatory-port with DDS (#70336)

Implements the following:
  - If both --host-vmservice-port and --dds-port are specified, use the current behavior
  - If only --host-vmservice-port is specified and dds is enabled, use that for the dds port
  - If only --dds-port is specified, use that for the dds port

Fixes https://github.com/flutter/flutter/issues/70332
parent 9b238a1f
......@@ -341,10 +341,27 @@ abstract class FlutterCommand extends Command<void> {
bool get disableDds => boolArg('disable-dds');
bool get _hostVmServicePortProvided => argResults.wasParsed('observatory-port') ||
argResults.wasParsed('host-vmservice-port');
int _tryParseHostVmservicePort() {
try {
return int.parse(stringArg('observatory-port') ?? stringArg('host-vmservice-port'));
} on FormatException catch (error) {
throwToolExit('Invalid port for `--observatory-port/--host-vmservice-port`: $error');
}
return null;
}
int get ddsPort {
if (argResults.wasParsed('dds-port')) {
if (!argResults.wasParsed('dds-port') && _hostVmServicePortProvided) {
// If an explicit DDS port is _not_ provided, use the host-vmservice-port for DDS.
return _tryParseHostVmservicePort();
} else if (argResults.wasParsed('dds-port')) {
// If an explicit DDS port is provided, use dds-port for DDS.
return int.tryParse(stringArg('dds-port')) ?? 0;
}
// Otherwise, DDS can bind to a random port.
return 0;
}
......@@ -356,9 +373,7 @@ abstract class FlutterCommand extends Command<void> {
///
/// If no port is set, returns null.
int get hostVmservicePort {
if (!_usesPortOption ||
(argResults['observatory-port'] == null &&
argResults['host-vmservice-port'] == null)) {
if (!_usesPortOption || !_hostVmServicePortProvided) {
return null;
}
if (argResults.wasParsed('observatory-port') &&
......@@ -366,12 +381,13 @@ abstract class FlutterCommand extends Command<void> {
throwToolExit('Only one of "--observatory-port" and '
'"--host-vmservice-port" may be specified.');
}
try {
return int.parse(stringArg('observatory-port') ?? stringArg('host-vmservice-port'));
} on FormatException catch (error) {
throwToolExit('Invalid port for `--observatory-port/--host-vmservice-port`: $error');
// If DDS is enabled and no explicit DDS port is provided, use the
// host-vmservice-port for DDS instead and bind the VM service to a random
// port.
if (!disableDds && !argResults.wasParsed('dds-port')) {
return null;
}
return null;
return _tryParseHostVmservicePort();
}
/// Gets the vmservice port provided to in the 'device-vmservice-port' option.
......
......@@ -526,6 +526,9 @@ void main() {
'$devicePort',
'--observatory-port',
'$hostPort',
// Ensure DDS doesn't use hostPort by binding to a random port.
'--dds-port',
'0',
],
);
await completer.future;
......@@ -558,6 +561,9 @@ void main() {
'--observatory-port',
'$hostPort',
'--ipv6',
// Ensure DDS doesn't use hostPort by binding to a random port.
'--dds-port',
'0',
],
);
await completer.future;
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:async';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/convert.dart';
import '../src/common.dart';
import '../src/context.dart';
import 'test_data/basic_project.dart';
import 'test_utils.dart';
Future<int> getFreePort() async {
int port = 0;
final ServerSocket serverSocket = await ServerSocket.bind(InternetAddress.loopbackIPv4, 0);
port = serverSocket.port;
await serverSocket.close();
return port;
}
Future<void> waitForObservatoryMessage(Process process, int port) async {
final Completer<void> completer = Completer<void>();
process.stdout
.transform(utf8.decoder)
.listen((String line) {
print(line);
if (line.contains('An Observatory debugger and profiler on Flutter test device is available at')) {
if (line.contains('http://127.0.0.1:$port')) {
completer.complete();
} else {
completer.completeError(Exception('Did not forward to provided port $port, instead found $line'));
}
}
});
process.stderr
.transform(utf8.decoder)
.listen(print);
return completer.future;
}
void main() {
Directory tempDir;
final BasicProject _project = BasicProject();
setUp(() async {
tempDir = createResolvedTempDirectorySync('run_test.');
await _project.setUpIn(tempDir);
});
tearDown(() async {
tryToDelete(tempDir);
});
testUsingContext('flutter run --observatory-port', () async {
final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
final int port = await getFreePort();
// If only --observatory-port is provided, --observatory-port will be used by DDS
// and the VM service will bind to a random port.
final Process process = await processManager.start(<String>[
flutterBin,
'run',
'--show-test-device',
'--observatory-port=$port',
'-d',
'flutter-tester',
], workingDirectory: tempDir.path);
await waitForObservatoryMessage(process, port);
process.kill();
await process.exitCode;
});
testUsingContext('flutter run --dds-port --observatory-port', () async {
final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
final int observatoryPort = await getFreePort();
int ddsPort = await getFreePort();
while(ddsPort == observatoryPort) {
ddsPort = await getFreePort();
}
// If both --dds-port and --observatory-port are provided, --dds-port will be used by
// DDS and --observatory-port will be used by the VM service.
final Process process = await processManager.start(<String>[
flutterBin,
'run',
'--show-test-device',
'--observatory-port=$observatoryPort',
'--dds-port=$ddsPort',
'-d',
'flutter-tester',
], workingDirectory: tempDir.path);
await waitForObservatoryMessage(process, ddsPort);
process.kill();
await process.exitCode;
});
testUsingContext('flutter run --dds-port', () async {
final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter');
final int ddsPort = await getFreePort();
// If only --dds-port is provided, --dds-port will be used by DDS and the VM service
// will bind to a random port.
final Process process = await processManager.start(<String>[
flutterBin,
'run',
'--show-test-device',
'--dds-port=$ddsPort',
'-d',
'flutter-tester',
], workingDirectory: tempDir.path);
await waitForObservatoryMessage(process, ddsPort);
process.kill();
await process.exitCode;
});
}
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