[flutter_tools] add debugging to ios/core_devices.dart (#142187)
Add debugging for #141892 to detect when the temp file mysteriously
disappears after running devicectl.
diff --git a/packages/flutter_tools/lib/src/ios/core_devices.dart b/packages/flutter_tools/lib/src/ios/core_devices.dart
index 1e49950..71a6526 100644
--- a/packages/flutter_tools/lib/src/ios/core_devices.dart
+++ b/packages/flutter_tools/lib/src/ios/core_devices.dart
@@ -78,8 +78,16 @@
];
try {
- await _processUtils.run(command, throwOnError: true);
+ final RunResult result = await _processUtils.run(command, throwOnError: true);
+ if (!output.existsSync()) {
+ _logger.printError('After running the command ${command.join(' ')} the file');
+ _logger.printError('${output.path} was expected to exist, but it did not.');
+ _logger.printError('The process exited with code ${result.exitCode} and');
+ _logger.printError('Stdout:\n\n${result.stdout.trim()}\n');
+ _logger.printError('Stderr:\n\n${result.stderr.trim()}');
+ throw StateError('Expected the file ${output.path} to exist but it did not');
+ }
final String stringOutput = output.readAsStringSync();
_logger.printTrace(stringOutput);
diff --git a/packages/flutter_tools/test/general.shard/ios/core_devices_test.dart b/packages/flutter_tools/test/general.shard/ios/core_devices_test.dart
index 1313b42..860947c 100644
--- a/packages/flutter_tools/test/general.shard/ios/core_devices_test.dart
+++ b/packages/flutter_tools/test/general.shard/ios/core_devices_test.dart
@@ -87,7 +87,7 @@
setUp(() {
logger = BufferLogger.test();
fakeProcessManager = FakeProcessManager.empty();
- // TODO(fujino): make this FakeProcessManager.empty()
+ // TODO(fujino): re-use fakeProcessManager
xcode = Xcode.test(processManager: FakeProcessManager.any());
deviceControl = IOSCoreDeviceControl(
logger: logger,
@@ -1355,6 +1355,51 @@
expect(fakeProcessManager, hasNoRemainingExpectations);
});
+ testWithoutContext('Handles json file mysteriously disappearing', () async {
+ final Directory tempDir = fileSystem.systemTempDirectory
+ .childDirectory('core_devices.rand0');
+ final File tempFile = tempDir.childFile('core_device_list.json');
+ final List<String> args = <String>[
+ 'xcrun',
+ 'devicectl',
+ 'list',
+ 'devices',
+ '--timeout',
+ '5',
+ '--json-output',
+ tempFile.path,
+ ];
+ fakeProcessManager.addCommand(FakeCommand(
+ command: args,
+ onRun: (_) {
+ // Simulate that this command deleted tempFile, did not create a
+ // new one, and exited successfully
+ expect(tempFile, exists);
+ tempFile.deleteSync();
+ expect(tempFile, isNot(exists));
+ },
+ ));
+
+ await expectLater(
+ () => deviceControl.getCoreDevices(),
+ throwsA(
+ isA<StateError>().having(
+ (StateError e) => e.message,
+ 'message',
+ contains('Expected the file ${tempFile.path} to exist but it did not'),
+ ),
+ ),
+ );
+ expect(
+ logger.errorText,
+ contains('After running the command xcrun devicectl list devices '
+ '--timeout 5 --json-output ${tempFile.path} the file\n'
+ '${tempFile.path} was expected to exist, but it did not',
+ ),
+ );
+ expect(fakeProcessManager, hasNoRemainingExpectations);
+ });
+
testWithoutContext('No devices', () async {
const String deviceControlOutput = '''
{
diff --git a/packages/flutter_tools/test/integration.shard/overall_experience_test.dart b/packages/flutter_tools/test/integration.shard/overall_experience_test.dart
index 8cc4fff..eddf735 100644
--- a/packages/flutter_tools/test/integration.shard/overall_experience_test.dart
+++ b/packages/flutter_tools/test/integration.shard/overall_experience_test.dart
@@ -66,15 +66,25 @@
tryToDelete(fileSystem.directory(tempDirectory));
}
}, skip: Platform.isWindows); // [intended] Windows doesn't support sending signals so we don't care if it can store the PID.
- testWithoutContext('flutter run handle SIGUSR1/2', () async {
+
+ testWithoutContext('flutter run handle SIGUSR1/2 run', () async {
final String tempDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_overall_experience_test.').resolveSymbolicLinksSync();
final String pidFile = fileSystem.path.join(tempDirectory, 'flutter.pid');
final String testDirectory = fileSystem.path.join(flutterRoot, 'dev', 'integration_tests', 'ui');
final String testScript = fileSystem.path.join('lib', 'commands.dart');
late int pid;
+ final List<String> command = <String>[
+ 'run',
+ '-dflutter-tester',
+ '--report-ready',
+ '--pid-file',
+ pidFile,
+ '--no-devtools',
+ testScript,
+ ];
try {
final ProcessTestResult result = await runFlutter(
- <String>['run', '-dflutter-tester', '--report-ready', '--pid-file', pidFile, '--no-devtools', testScript],
+ command,
testDirectory,
<Transition>[
Multiple(<Pattern>['Flutter run key commands.', 'called paint'], handler: (String line) {
@@ -108,16 +118,22 @@
'called main',
'called paint',
]);
- expect(result.stdout.where((String line) => !line.startsWith('called ')), <Object>[
- // logs start after we receive the response to sending SIGUSR1
- 'Performing hot reload...'.padRight(progressMessageWidth),
- startsWith('Reloaded 0 libraries in '),
- 'Performing hot restart...'.padRight(progressMessageWidth),
- startsWith('Restarted application in '),
- '', // this newline is the one for after we hit "q"
- 'Application finished.',
- 'ready',
- ]);
+ expect(
+ result.stdout.where((String line) => !line.startsWith('called ')),
+ <Object>[
+ // logs start after we receive the response to sending SIGUSR1
+ 'Performing hot reload...'.padRight(progressMessageWidth),
+ startsWith('Reloaded 0 libraries in '),
+ 'Performing hot restart...'.padRight(progressMessageWidth),
+ startsWith('Restarted application in '),
+ '', // this newline is the one for after we hit "q"
+ 'Application finished.',
+ 'ready',
+ ],
+ reason: 'stdout from command ${command.join(' ')} was unexpected, '
+ 'full Stdout:\n\n${result.stdout.join('\n')}\n\n'
+ 'Stderr:\n\n${result.stderr.join('\n')}',
+ );
expect(result.exitCode, 0);
} finally {
tryToDelete(fileSystem.directory(tempDirectory));
@@ -128,9 +144,16 @@
final String tempDirectory = fileSystem.systemTempDirectory.createTempSync('flutter_overall_experience_test.').resolveSymbolicLinksSync();
final String testDirectory = fileSystem.path.join(flutterRoot, 'dev', 'integration_tests', 'ui');
final String testScript = fileSystem.path.join('lib', 'commands.dart');
+ final List<String> command = <String>[
+ 'run',
+ '-dflutter-tester',
+ '--report-ready',
+ '--no-devtools',
+ testScript,
+ ];
try {
final ProcessTestResult result = await runFlutter(
- <String>['run', '-dflutter-tester', '--report-ready', '--no-devtools', testScript],
+ command,
testDirectory,
<Transition>[
Multiple(<Pattern>['Flutter run key commands.', 'called main', 'called paint'], handler: (String line) {
@@ -171,23 +194,28 @@
// debugPaintSizeEnabled = false:
'called paint',
]);
- expect(result.stdout.where((String line) => !line.startsWith('called ')), <Object>[
- // logs start after we receive the response to hitting "r"
- 'Performing hot reload...'.padRight(progressMessageWidth),
- startsWith('Reloaded 0 libraries in '),
- 'ready',
- '', // this newline is the one for after we hit "R"
- 'Performing hot restart...'.padRight(progressMessageWidth),
- startsWith('Restarted application in '),
- 'ready',
- '', // newline for after we hit "p" the first time
- 'ready',
- '', // newline for after we hit "p" the second time
- 'ready',
- '', // this newline is the one for after we hit "q"
- 'Application finished.',
- 'ready',
- ]);
+ expect(
+ result.stdout.where((String line) => !line.startsWith('called ')), <Object>[
+ // logs start after we receive the response to hitting "r"
+ 'Performing hot reload...'.padRight(progressMessageWidth),
+ startsWith('Reloaded 0 libraries in '),
+ 'ready',
+ '', // this newline is the one for after we hit "R"
+ 'Performing hot restart...'.padRight(progressMessageWidth),
+ startsWith('Restarted application in '),
+ 'ready',
+ '', // newline for after we hit "p" the first time
+ 'ready',
+ '', // newline for after we hit "p" the second time
+ 'ready',
+ '', // this newline is the one for after we hit "q"
+ 'Application finished.',
+ 'ready',
+ ],
+ reason: 'stdout from command ${command.join(' ')} was unexpected, '
+ 'full Stdout:\n\n${result.stdout.join('\n')}\n\n'
+ 'Stderr:\n\n${result.stderr.join('\n')}',
+ );
expect(result.exitCode, 0);
} finally {
tryToDelete(fileSystem.directory(tempDirectory));
diff --git a/packages/flutter_tools/test/integration.shard/transition_test_utils.dart b/packages/flutter_tools/test/integration.shard/transition_test_utils.dart
index fa3a7f3..3b187f2 100644
--- a/packages/flutter_tools/test/integration.shard/transition_test_utils.dart
+++ b/packages/flutter_tools/test/integration.shard/transition_test_utils.dart
@@ -175,8 +175,8 @@
bool debug = false,
bool logging = true,
Duration expectedMaxDuration = const Duration(
- minutes:
- 10), // must be less than test timeout of 15 minutes! See ../../dart_test.yaml.
+ minutes: 10,
+ ), // must be less than test timeout of 15 minutes! See ../../dart_test.yaml.
}) async {
const LocalPlatform platform = LocalPlatform();
final Stopwatch clock = Stopwatch()..start();