[fuchsia] Get Dart VM service ports from The Hub (#25332)
This commit is contained in:
parent
9619b53d06
commit
b18a2b1794
@ -13,9 +13,6 @@ import 'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart
|
||||
|
||||
import 'error.dart';
|
||||
|
||||
// TODO(awdavies): Update this to use the hub.
|
||||
final Directory _kDartPortDir = Directory('/tmp/dart.services');
|
||||
|
||||
class _DummyPortForwarder implements PortForwarder {
|
||||
_DummyPortForwarder(this._port, this._remotePort);
|
||||
|
||||
@ -49,13 +46,13 @@ class _DummySshCommandRunner implements SshCommandRunner {
|
||||
@override
|
||||
Future<List<String>> run(String command) async {
|
||||
try {
|
||||
return List<String>.of(_kDartPortDir
|
||||
.listSync(recursive: false, followLinks: false)
|
||||
.map((FileSystemEntity entity) => entity.path
|
||||
.replaceAll(entity.parent.path, '')
|
||||
.replaceFirst(Platform.pathSeparator, '')));
|
||||
} on FileSystemException catch (e) {
|
||||
_log.warning('Error listing directory: $e');
|
||||
final List<String> splitCommand = command.split(' ');
|
||||
final String exe = splitCommand[0];
|
||||
final List<String> args = splitCommand.skip(1).toList();
|
||||
final ProcessResult r = Process.runSync(exe, args);
|
||||
return r.stdout.split('\n');
|
||||
} on ProcessException catch (e) {
|
||||
_log.warning("Error running '$command': $e");
|
||||
}
|
||||
return <String>[];
|
||||
}
|
||||
|
@ -216,8 +216,28 @@ class FuchsiaDevice extends Device {
|
||||
|
||||
/// List the ports currently running a dart observatory.
|
||||
Future<List<int>> servicePorts() async {
|
||||
final String lsOutput = await shell('ls /tmp/dart.services');
|
||||
return parseFuchsiaDartPortOutput(lsOutput);
|
||||
final String findOutput = await shell('find /hub -name vmservice-port');
|
||||
if (findOutput.trim() == '') {
|
||||
throwToolExit('No Dart Observatories found. Are you running a debug build?');
|
||||
return null;
|
||||
}
|
||||
final List<int> ports = <int>[];
|
||||
for (String path in findOutput.split('\n')) {
|
||||
if (path == '') {
|
||||
continue;
|
||||
}
|
||||
final String lsOutput = await shell('ls $path');
|
||||
for (String line in lsOutput.split('\n')) {
|
||||
if (line == '') {
|
||||
continue;
|
||||
}
|
||||
final int port = int.tryParse(line);
|
||||
if (port != null) {
|
||||
ports.add(port);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ports;
|
||||
}
|
||||
|
||||
/// Run `command` on the Fuchsia device shell.
|
||||
@ -225,9 +245,6 @@ class FuchsiaDevice extends Device {
|
||||
final RunResult result = await runAsync(<String>[
|
||||
'ssh', '-F', fuchsiaArtifacts.sshConfig.absolute.path, id, command]);
|
||||
if (result.exitCode != 0) {
|
||||
if (result.stderr.contains('/tmp/dart.services: No such file or directory')) {
|
||||
throwToolExit('No Dart Observatories found. Are you running a debug build?');
|
||||
}
|
||||
throwToolExit('Command failed: $command\nstdout: ${result.stdout}\nstderr: ${result.stderr}');
|
||||
return null;
|
||||
}
|
||||
@ -336,28 +353,3 @@ class FuchsiaModulePackage extends ApplicationPackage {
|
||||
@override
|
||||
final String name;
|
||||
}
|
||||
|
||||
/// Parses output from `dart.services` output on a fuchsia device.
|
||||
///
|
||||
/// Example output:
|
||||
/// $ ls /tmp/dart.services
|
||||
/// > d 2 0 .
|
||||
/// > - 1 0 36780
|
||||
@visibleForTesting
|
||||
List<int> parseFuchsiaDartPortOutput(String text) {
|
||||
final List<int> ports = <int>[];
|
||||
if (text == null)
|
||||
return ports;
|
||||
for (String line in text.split('\n')) {
|
||||
final String trimmed = line.trim();
|
||||
final int lastSpace = trimmed.lastIndexOf(' ');
|
||||
final String lastWord = trimmed.substring(lastSpace + 1);
|
||||
if ((lastWord != '.') && (lastWord != '..')) {
|
||||
final int value = int.tryParse(lastWord);
|
||||
if (value != null) {
|
||||
ports.add(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ports;
|
||||
}
|
||||
|
@ -36,16 +36,6 @@ void main() {
|
||||
expect(names.length, 1);
|
||||
expect(names.first, 'lilia-shore-only-last');
|
||||
});
|
||||
|
||||
test('parse ls tmp/dart.servies output', () {
|
||||
const String example = '''
|
||||
d 2 0 .
|
||||
'- 1 0 36780
|
||||
''';
|
||||
final List<int> ports = parseFuchsiaDartPortOutput(example);
|
||||
expect(ports.length, 1);
|
||||
expect(ports.single, 36780);
|
||||
});
|
||||
});
|
||||
|
||||
group('displays friendly error when', () {
|
||||
@ -60,7 +50,7 @@ d 2 0 .
|
||||
)).thenAnswer((Invocation invocation) => Future<ProcessResult>.value(mockProcessResult));
|
||||
when(mockProcessResult.exitCode).thenReturn(1);
|
||||
when<String>(mockProcessResult.stdout).thenReturn('');
|
||||
when<String>(mockProcessResult.stderr).thenReturn('ls: lstat /tmp/dart.services: No such file or directory');
|
||||
when<String>(mockProcessResult.stderr).thenReturn('');
|
||||
when(mockFuchsiaArtifacts.sshConfig).thenReturn(mockFile);
|
||||
when(mockFile.absolute).thenReturn(mockFile);
|
||||
when(mockFile.path).thenReturn('');
|
||||
@ -78,7 +68,18 @@ d 2 0 .
|
||||
ProcessManager: () => mockProcessManager,
|
||||
});
|
||||
|
||||
testUsingContext('with BUILD_DIR set', () async {
|
||||
final MockProcessManager emptyStdoutProcessManager = MockProcessManager();
|
||||
final MockProcessResult emptyStdoutProcessResult = MockProcessResult();
|
||||
when(emptyStdoutProcessManager.run(
|
||||
any,
|
||||
environment: anyNamed('environment'),
|
||||
workingDirectory: anyNamed('workingDirectory'),
|
||||
)).thenAnswer((Invocation invocation) => Future<ProcessResult>.value(emptyStdoutProcessResult));
|
||||
when(emptyStdoutProcessResult.exitCode).thenReturn(0);
|
||||
when<String>(emptyStdoutProcessResult.stdout).thenReturn('');
|
||||
when<String>(emptyStdoutProcessResult.stderr).thenReturn('');
|
||||
|
||||
testUsingContext('No vmservices found', () async {
|
||||
final FuchsiaDevice device = FuchsiaDevice('id');
|
||||
ToolExit toolExit;
|
||||
try {
|
||||
@ -86,9 +87,9 @@ d 2 0 .
|
||||
} on ToolExit catch (err) {
|
||||
toolExit = err;
|
||||
}
|
||||
expect(toolExit.message, 'No Dart Observatories found. Are you running a debug build?');
|
||||
expect(toolExit.message, contains('No Dart Observatories found. Are you running a debug build?'));
|
||||
}, overrides: <Type, Generator>{
|
||||
ProcessManager: () => mockProcessManager,
|
||||
ProcessManager: () => emptyStdoutProcessManager,
|
||||
FuchsiaArtifacts: () => mockFuchsiaArtifacts,
|
||||
});
|
||||
|
||||
|
@ -523,24 +523,21 @@ class FuchsiaRemoteConnection {
|
||||
/// found. An exception is thrown in the event of an actual error when
|
||||
/// attempting to acquire the ports.
|
||||
Future<List<int>> getDeviceServicePorts() async {
|
||||
// TODO(awdavies): This is using a temporary workaround rather than a
|
||||
// well-defined service, and will be deprecated in the near future.
|
||||
final List<String> lsOutput =
|
||||
await _sshCommandRunner.run('ls /tmp/dart.services');
|
||||
final List<String> portPaths =
|
||||
await _sshCommandRunner.run('find /hub -name vmservice-port');
|
||||
final List<int> ports = <int>[];
|
||||
|
||||
// The output of lsOutput is a list of available ports as the Fuchsia dart
|
||||
// service advertises. An example lsOutput would look like:
|
||||
//
|
||||
// [ '31782\n', '1234\n', '11967' ]
|
||||
for (String s in lsOutput) {
|
||||
final String trimmed = s.trim();
|
||||
final int lastSpace = trimmed.lastIndexOf(' ');
|
||||
final String lastWord = trimmed.substring(lastSpace + 1);
|
||||
if ((lastWord != '.') && (lastWord != '..')) {
|
||||
final int value = int.tryParse(lastWord);
|
||||
if (value != null) {
|
||||
ports.add(value);
|
||||
for (String path in portPaths) {
|
||||
if (path == '') {
|
||||
continue;
|
||||
}
|
||||
final List<String> lsOutput = await _sshCommandRunner.run('ls $path');
|
||||
for (String line in lsOutput) {
|
||||
if (line == '') {
|
||||
continue;
|
||||
}
|
||||
final int port = int.tryParse(line);
|
||||
if (port != null) {
|
||||
ports.add(port);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,9 @@ void main() {
|
||||
setUp(() {
|
||||
mockRunner = MockSshCommandRunner();
|
||||
// Adds some extra junk to make sure the strings will be cleaned up.
|
||||
when(mockRunner.run(any)).thenAnswer((_) =>
|
||||
when(mockRunner.run(argThat(startsWith('find')))).thenAnswer((_) =>
|
||||
Future<List<String>>.value(<String>['/hub/blah/blah/blah/vmservice-port\n']));
|
||||
when(mockRunner.run(argThat(startsWith('ls')))).thenAnswer((_) =>
|
||||
Future<List<String>>.value(<String>['123\n\n\n', '456 ', '789']));
|
||||
const String address = 'fe80::8eae:4cff:fef4:9247';
|
||||
const String interface = 'eno1';
|
||||
|
Loading…
x
Reference in New Issue
Block a user