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}) {
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
// character.
class _AnsiRun {
......
......@@ -7,6 +7,7 @@ import 'dart:async';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/utils.dart';
import '../cache.dart';
import '../commands/daemon.dart';
import '../device.dart';
......@@ -44,6 +45,10 @@ class AttachCommand extends FlutterCommand {
..addOption(
'debug-port',
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(
'project-root',
hide: !verboseHelp,
......@@ -90,6 +95,8 @@ class AttachCommand extends FlutterCommand {
await _validateArguments();
writePidFile(argResults['pid-file']);
final Device device = await findTargetDevice();
final int devicePort = observatoryPort;
......
......@@ -6,7 +6,6 @@ import 'dart:async';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/io.dart';
import '../base/utils.dart';
import '../build_info.dart';
import '../cache.dart';
......@@ -276,6 +275,8 @@ class RunCommand extends RunCommandBase {
// debug mode.
final bool hotMode = shouldUseHotMode();
writePidFile(argResults['pid-file']);
if (argResults['machine']) {
if (devices.length > 1)
throwToolExit('--machine does not support -d all.');
......@@ -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) {
return FlutterDevice(
device,
......
......@@ -29,6 +29,15 @@ void main() {
});
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 {
await _flutterRun.run(withDebugger: true);
await _flutterAttach.attach(_flutterRun.vmServicePort);
......
......@@ -9,21 +9,25 @@ import 'package:process/process.dart';
import '../src/common.dart';
import 'test_data/basic_project.dart';
import 'test_driver.dart';
import 'test_utils.dart';
void main() {
group('flutter_run', () {
Directory tempDir;
final BasicProject _project = BasicProject();
FlutterTestDriver _flutter;
setUp(() async {
tempDir = createResolvedTempDirectorySync();
await _project.setUpIn(tempDir);
_flutter = FlutterTestDriver(tempDir);
});
tearDown(() async {
tryToDelete(tempDir);
});
test('reports an error if an invalid device is supplied', () async {
// This test forces flutter to check for all possible devices to catch issues
// like https://github.com/flutter/flutter/issues/21418 which were skipped
......@@ -44,5 +48,11 @@ void main() {
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));
}
......@@ -56,16 +56,25 @@ class FlutterTestDriver {
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>[
'run',
'--machine',
'-d',
'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>[
'attach',
'--machine',
......@@ -73,20 +82,28 @@ class FlutterTestDriver {
'flutter-tester',
'--debug-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 List<String> flutterArgs = withDebugger
? args.followedBy(<String>['--start-paused']).toList()
: args;
_debugPrint('Spawning flutter $flutterArgs in ${_projectFolder.path}');
if (withDebugger) {
args.add('--start-paused');
}
if (pidFile != null) {
args.addAll(<String>['--pid-file', pidFile.path]);
}
_debugPrint('Spawning flutter $args in ${_projectFolder.path}');
const ProcessManager _processManager = LocalProcessManager();
_proc = await _processManager.start(
<String>[flutterBin]
.followedBy(flutterArgs)
.followedBy(args)
.toList(),
workingDirectory: _projectFolder.path,
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