Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 8984ada

Browse files
authored
Scenario App: Adds a run_{count}.{backend}. file prefix to every run (on CI) (#51102)
Adds a flag, `--prefix-logs-per-run`, that defaults to `true` on CI envrionments. If present, instead of writing the file `${LOGS_DIR}/logcat.txt`, we write `${LOGS_DIR}/{prefix}.logcat.txt`. I don't really like this solution, but alternatives are using zip files (requires downloading to view) or waiting on generic log improvements. Closes flutter/flutter#144402.
1 parent 8274a4f commit 8984ada

File tree

2 files changed

+78
-5
lines changed

2 files changed

+78
-5
lines changed

testing/scenario_app/bin/run_android_tests.dart

Lines changed: 70 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ void main(List<String> args) async {
7979
contentsGolden: options.outputContentsGolden,
8080
ndkStack: options.ndkStack,
8181
forceSurfaceProducerSurfaceTexture: options.forceSurfaceProducerSurfaceTexture,
82+
prefixLogsPerRun: options.prefixLogsPerRun,
8283
);
8384
onSigint.cancel();
8485
exit(0);
@@ -122,15 +123,22 @@ Future<void> _run({
122123
required String? contentsGolden,
123124
required String ndkStack,
124125
required bool forceSurfaceProducerSurfaceTexture,
126+
required bool prefixLogsPerRun,
125127
}) async {
126128
const ProcessManager pm = LocalProcessManager();
127129
final String scenarioAppPath = join(outDir.path, 'scenario_app');
130+
131+
// Due to the CI environment, the logs directory persists between runs and
132+
// even different builds. Because we're checking the output directory after
133+
// each run, we need a clean logs directory to avoid false positives.
134+
//
135+
// Only after the runner is done, we can move the logs to the final location.
136+
//
137+
// See [_copyFiles] below and https://github.com/flutter/flutter/issues/144402.
138+
final Directory finalLogsDir = logsDir..createSync(recursive: true);
139+
logsDir = Directory.systemTemp.createTempSync('scenario_app_test_logs.');
128140
final String logcatPath = join(logsDir.path, 'logcat.txt');
129141

130-
// TODO(matanlurey): Use screenshots/ sub-directory (https://github.com/flutter/flutter/issues/143604).
131-
if (!logsDir.existsSync()) {
132-
logsDir.createSync(recursive: true);
133-
}
134142
final String screenshotPath = logsDir.path;
135143
final String apkOutPath = join(scenarioAppPath, 'app', 'outputs', 'apk');
136144
final File testApk = File(join(apkOutPath, 'androidTest', 'debug', 'app-debug-androidTest.apk'));
@@ -388,6 +396,32 @@ Future<void> _run({
388396
await logcat.flush();
389397
await logcat.close();
390398
log('wrote logcat to $logcatPath');
399+
400+
// Copy the logs to the final location.
401+
// Optionally prefix the logs with a run number and backend name.
402+
// See https://github.com/flutter/flutter/issues/144402.
403+
final StringBuffer prefix = StringBuffer();
404+
if (prefixLogsPerRun) {
405+
final int rerunNumber = _getAndIncrementRerunNumber(finalLogsDir.path);
406+
prefix.write('run_$rerunNumber.');
407+
if (enableImpeller) {
408+
prefix.write('impeller');
409+
} else {
410+
prefix.write('skia');
411+
}
412+
if (enableImpeller) {
413+
prefix.write('_${impellerBackend!.name}');
414+
}
415+
if (forceSurfaceProducerSurfaceTexture) {
416+
prefix.write('_force-st');
417+
}
418+
prefix.write('.');
419+
}
420+
_copyFiles(
421+
source: logsDir,
422+
destination: finalLogsDir,
423+
prefix: prefix.toString(),
424+
);
391425
});
392426

393427
if (enableImpeller) {
@@ -448,7 +482,9 @@ Future<void> _run({
448482
await Future.wait(pendingComparisons);
449483
});
450484

451-
if (contentsGolden != null) {
485+
final bool allTestsRun = smokeTestFullPath == null;
486+
final bool checkGoldens = contentsGolden != null;
487+
if (allTestsRun && checkGoldens) {
452488
// Check the output here.
453489
await step('Check output files...', () async {
454490
// TODO(matanlurey): Resolve this in a better way. On CI this file always exists.
@@ -476,3 +512,32 @@ void _withTemporaryCwd(String path, void Function() callback) {
476512
Directory.current = originalCwd;
477513
}
478514
}
515+
516+
/// Reads the file named `reruns.txt` in the logs directory and returns the number of reruns.
517+
///
518+
/// If the file does not exist, it is created with the number 1 and that number is returned.
519+
int _getAndIncrementRerunNumber(String logsDir) {
520+
final File rerunFile = File(join(logsDir, 'reruns.txt'));
521+
if (!rerunFile.existsSync()) {
522+
rerunFile.writeAsStringSync('1');
523+
return 1;
524+
}
525+
final int rerunNumber = int.parse(rerunFile.readAsStringSync()) + 1;
526+
rerunFile.writeAsStringSync(rerunNumber.toString());
527+
return rerunNumber;
528+
}
529+
530+
/// Copies the contents of [source] to [destination], optionally adding a [prefix] to the destination path.
531+
///
532+
/// This function is used to copy the screenshots from the device to the logs directory.
533+
void _copyFiles({
534+
required Directory source,
535+
required Directory destination,
536+
String prefix = '',
537+
}) {
538+
for (final FileSystemEntity entity in source.listSync()) {
539+
if (entity is File) {
540+
entity.copySync(join(destination.path, prefix + basename(entity.path)));
541+
}
542+
}
543+
}

testing/scenario_app/bin/utils/options.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ extension type const Options._(ArgResults _args) {
159159
'https://github.com/flutter/flutter/issues/143539 for details.',
160160
negatable: false
161161
)
162+
..addFlag(
163+
'prefix-logs-per-run',
164+
help: 'Whether to prefix logs with a per-run unique identifier.',
165+
defaultsTo: environment.isCi,
166+
)
162167
..addOption(
163168
'impeller-backend',
164169
help: 'The graphics backend to use when --enable-impeller is true. '
@@ -314,4 +319,7 @@ extension type const Options._(ArgResults _args) {
314319
}
315320
return _args['force-surface-producer-surface-texture'] as bool;
316321
}
322+
323+
/// Whether to prefix logs with a per-run unique identifier.
324+
bool get prefixLogsPerRun => _args['prefix-logs-per-run'] as bool;
317325
}

0 commit comments

Comments
 (0)