Unverified Commit aa83f77a authored by Danny Tuppeny's avatar Danny Tuppeny Committed by GitHub

Fix --pid-file not working for --machine + add to attach command (#23242)

* Fix --pid-file not working for --machine + add to attach

Fixes #23201.

* Add tests for --pid-file in run+attach
parent b21d0de0
...@@ -398,6 +398,13 @@ String wrapText(String text, {int columnWidth, int hangingIndent, int indent}) { ...@@ -398,6 +398,13 @@ String wrapText(String text, {int columnWidth, int hangingIndent, int indent}) {
return result.join('\n'); return result.join('\n');
} }
void writePidFile(String pidFile) {
if (pidFile != null) {
// Write our pid to the file.
fs.file(pidFile).writeAsStringSync(io.pid.toString());
}
}
// Used to represent a run of ANSI control sequences next to a visible // Used to represent a run of ANSI control sequences next to a visible
// character. // character.
class _AnsiRun { class _AnsiRun {
......
...@@ -7,6 +7,7 @@ import 'dart:async'; ...@@ -7,6 +7,7 @@ import 'dart:async';
import '../base/common.dart'; import '../base/common.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart'; import '../base/io.dart';
import '../base/utils.dart';
import '../cache.dart'; import '../cache.dart';
import '../commands/daemon.dart'; import '../commands/daemon.dart';
import '../device.dart'; import '../device.dart';
...@@ -44,6 +45,10 @@ class AttachCommand extends FlutterCommand { ...@@ -44,6 +45,10 @@ class AttachCommand extends FlutterCommand {
..addOption( ..addOption(
'debug-port', 'debug-port',
help: 'Local port where the observatory is listening.', help: 'Local port where the observatory is listening.',
)..addOption('pid-file',
help: 'Specify a file to write the process id to. '
'You can send SIGUSR1 to trigger a hot reload '
'and SIGUSR2 to trigger a hot restart.',
)..addOption( )..addOption(
'project-root', 'project-root',
hide: !verboseHelp, hide: !verboseHelp,
...@@ -90,6 +95,8 @@ class AttachCommand extends FlutterCommand { ...@@ -90,6 +95,8 @@ class AttachCommand extends FlutterCommand {
await _validateArguments(); await _validateArguments();
writePidFile(argResults['pid-file']);
final Device device = await findTargetDevice(); final Device device = await findTargetDevice();
final int devicePort = observatoryPort; final int devicePort = observatoryPort;
......
...@@ -6,7 +6,6 @@ import 'dart:async'; ...@@ -6,7 +6,6 @@ import 'dart:async';
import '../base/common.dart'; import '../base/common.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../base/io.dart';
import '../base/utils.dart'; import '../base/utils.dart';
import '../build_info.dart'; import '../build_info.dart';
import '../cache.dart'; import '../cache.dart';
...@@ -276,6 +275,8 @@ class RunCommand extends RunCommandBase { ...@@ -276,6 +275,8 @@ class RunCommand extends RunCommandBase {
// debug mode. // debug mode.
final bool hotMode = shouldUseHotMode(); final bool hotMode = shouldUseHotMode();
writePidFile(argResults['pid-file']);
if (argResults['machine']) { if (argResults['machine']) {
if (devices.length > 1) if (devices.length > 1)
throwToolExit('--machine does not support -d all.'); throwToolExit('--machine does not support -d all.');
...@@ -340,12 +341,6 @@ class RunCommand extends RunCommandBase { ...@@ -340,12 +341,6 @@ class RunCommand extends RunCommandBase {
} }
} }
final String pidFile = argResults['pid-file'];
if (pidFile != null) {
// Write our pid to the file.
fs.file(pidFile).writeAsStringSync(pid.toString());
}
final List<FlutterDevice> flutterDevices = devices.map<FlutterDevice>((Device device) { final List<FlutterDevice> flutterDevices = devices.map<FlutterDevice>((Device device) {
return FlutterDevice( return FlutterDevice(
device, device,
......
...@@ -29,6 +29,15 @@ void main() { ...@@ -29,6 +29,15 @@ void main() {
}); });
group('attached process', () { group('attached process', () {
test('writes pid-file', () async {
final File pidFile = tempDir.childFile('test.pid');
await _flutterRun.run(withDebugger: true);
await _flutterAttach.attach(
_flutterRun.vmServicePort,
pidFile: pidFile,
);
expect(pidFile.existsSync(), isTrue);
});
test('can hot reload', () async { test('can hot reload', () async {
await _flutterRun.run(withDebugger: true); await _flutterRun.run(withDebugger: true);
await _flutterAttach.attach(_flutterRun.vmServicePort); await _flutterAttach.attach(_flutterRun.vmServicePort);
......
...@@ -9,21 +9,25 @@ import 'package:process/process.dart'; ...@@ -9,21 +9,25 @@ import 'package:process/process.dart';
import '../src/common.dart'; import '../src/common.dart';
import 'test_data/basic_project.dart'; import 'test_data/basic_project.dart';
import 'test_driver.dart';
import 'test_utils.dart'; import 'test_utils.dart';
void main() { void main() {
group('flutter_run', () { group('flutter_run', () {
Directory tempDir; Directory tempDir;
final BasicProject _project = BasicProject(); final BasicProject _project = BasicProject();
FlutterTestDriver _flutter;
setUp(() async { setUp(() async {
tempDir = createResolvedTempDirectorySync(); tempDir = createResolvedTempDirectorySync();
await _project.setUpIn(tempDir); await _project.setUpIn(tempDir);
_flutter = FlutterTestDriver(tempDir);
}); });
tearDown(() async { tearDown(() async {
tryToDelete(tempDir); tryToDelete(tempDir);
}); });
test('reports an error if an invalid device is supplied', () async { test('reports an error if an invalid device is supplied', () async {
// This test forces flutter to check for all possible devices to catch issues // This test forces flutter to check for all possible devices to catch issues
// like https://github.com/flutter/flutter/issues/21418 which were skipped // like https://github.com/flutter/flutter/issues/21418 which were skipped
...@@ -44,5 +48,11 @@ void main() { ...@@ -44,5 +48,11 @@ void main() {
fail("'flutter run -d invalid-device-id' did not produce the expected error"); fail("'flutter run -d invalid-device-id' did not produce the expected error");
} }
}); });
test('writes pid-file', () async {
final File pidFile = tempDir.childFile('test.pid');
await _flutter.run(pidFile: pidFile);
expect(pidFile.existsSync(), isTrue);
});
}, timeout: const Timeout.factor(6)); }, timeout: const Timeout.factor(6));
} }
...@@ -56,16 +56,25 @@ class FlutterTestDriver { ...@@ -56,16 +56,25 @@ class FlutterTestDriver {
return msg; return msg;
} }
Future<void> run({bool withDebugger = false, bool pauseOnExceptions = false}) async { Future<void> run({
bool withDebugger = false,
bool pauseOnExceptions = false,
File pidFile,
}) async {
await _setupProcess(<String>[ await _setupProcess(<String>[
'run', 'run',
'--machine', '--machine',
'-d', '-d',
'flutter-tester', 'flutter-tester',
], withDebugger: withDebugger, pauseOnExceptions: pauseOnExceptions); ], withDebugger: withDebugger, pauseOnExceptions: pauseOnExceptions, pidFile: pidFile);
} }
Future<void> attach(int port, {bool withDebugger = false, bool pauseOnExceptions = false}) async { Future<void> attach(
int port, {
bool withDebugger = false,
bool pauseOnExceptions = false,
File pidFile,
}) async {
await _setupProcess(<String>[ await _setupProcess(<String>[
'attach', 'attach',
'--machine', '--machine',
...@@ -73,20 +82,28 @@ class FlutterTestDriver { ...@@ -73,20 +82,28 @@ class FlutterTestDriver {
'flutter-tester', 'flutter-tester',
'--debug-port', '--debug-port',
'$port', '$port',
], withDebugger: withDebugger, pauseOnExceptions: pauseOnExceptions); ], withDebugger: withDebugger, pauseOnExceptions: pauseOnExceptions, pidFile: pidFile);
} }
Future<void> _setupProcess(List<String> args, {bool withDebugger = false, bool pauseOnExceptions = false}) async { Future<void> _setupProcess(
List<String> args, {
bool withDebugger = false,
bool pauseOnExceptions = false,
File pidFile,
}) async {
final String flutterBin = fs.path.join(getFlutterRoot(), 'bin', 'flutter'); final String flutterBin = fs.path.join(getFlutterRoot(), 'bin', 'flutter');
final List<String> flutterArgs = withDebugger if (withDebugger) {
? args.followedBy(<String>['--start-paused']).toList() args.add('--start-paused');
: args; }
_debugPrint('Spawning flutter $flutterArgs in ${_projectFolder.path}'); if (pidFile != null) {
args.addAll(<String>['--pid-file', pidFile.path]);
}
_debugPrint('Spawning flutter $args in ${_projectFolder.path}');
const ProcessManager _processManager = LocalProcessManager(); const ProcessManager _processManager = LocalProcessManager();
_proc = await _processManager.start( _proc = await _processManager.start(
<String>[flutterBin] <String>[flutterBin]
.followedBy(flutterArgs) .followedBy(args)
.toList(), .toList(),
workingDirectory: _projectFolder.path, workingDirectory: _projectFolder.path,
environment: <String, String>{'FLUTTER_TEST': 'true'}); environment: <String, String>{'FLUTTER_TEST': 'true'});
......
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