Skip to content

Commit 69a00e5

Browse files
committed
fix: cleanup .test_optimizer.dart on SIGINT
1 parent 9ec06bd commit 69a00e5

File tree

2 files changed

+103
-3
lines changed

2 files changed

+103
-3
lines changed

lib/src/cli/flutter_cli.dart

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,45 @@
1+
// ignore_for_file: public_member_api_docs
2+
13
part of 'cli.dart';
24

35
const _testOptimizerFileName = '.test_optimizer.dart';
46

7+
abstract class ProcessSignalOverrides {
8+
static final _token = Object();
9+
StreamController<ProcessSignal>? _sigintStreamController;
10+
11+
static ProcessSignalOverrides? get current {
12+
return Zone.current[_token] as ProcessSignalOverrides?;
13+
}
14+
15+
static R runZoned<R>(
16+
R Function() body, {
17+
Stream<ProcessSignal>? sigintStream,
18+
}) {
19+
final overrides = _ProcessSignalOverridesScope(sigintStream);
20+
return _asyncRunZoned(body, zoneValues: {_token: overrides});
21+
}
22+
23+
Stream<ProcessSignal>? get sigintWatch;
24+
25+
void addSIGINT() {
26+
_sigintStreamController?.add(ProcessSignal.sigint);
27+
}
28+
}
29+
30+
class _ProcessSignalOverridesScope extends ProcessSignalOverrides {
31+
_ProcessSignalOverridesScope(Stream<ProcessSignal>? mockSigintStream) {
32+
if (mockSigintStream != null) {
33+
_sigintStreamController = StreamController<ProcessSignal>();
34+
}
35+
}
36+
37+
@override
38+
Stream<ProcessSignal>? get sigintWatch {
39+
return _sigintStreamController?.stream;
40+
}
41+
}
42+
543
/// Thrown when `flutter pub get` is executed without a `pubspec.yaml`.
644
class PubspecNotFound implements Exception {}
745

@@ -211,9 +249,7 @@ class Flutter {
211249
stderr: stderr ?? noop,
212250
).whenComplete(() async {
213251
if (optimizePerformance) {
214-
File(p.join(cwd, 'test', _testOptimizerFileName))
215-
.delete()
216-
.ignore();
252+
await _cleanupOptimizerFile(cwd);
217253
}
218254

219255
if (collectCoverage) {
@@ -325,6 +361,8 @@ Future<int> _flutterTest({
325361
final groups = <int, TestGroup>{};
326362
final tests = <int, Test>{};
327363
final failedTestErrorMessages = <String, List<String>>{};
364+
final sigintWatch = ProcessSignalOverrides.current?.sigintWatch ??
365+
ProcessSignal.sigint.watch();
328366

329367
var successCount = 0;
330368
var skipCount = 0;
@@ -351,6 +389,15 @@ Future<int> _flutterTest({
351389
);
352390

353391
late final StreamSubscription<TestEvent> subscription;
392+
late final StreamSubscription<ProcessSignal> sigintWatchSubscription;
393+
394+
sigintWatchSubscription = sigintWatch.listen((_) async {
395+
await _cleanupOptimizerFile(cwd);
396+
await subscription.cancel();
397+
await sigintWatchSubscription.cancel();
398+
return completer.complete(ExitCode.success.code);
399+
});
400+
354401
subscription = testRunner(
355402
workingDirectory: cwd,
356403
arguments: [
@@ -483,6 +530,8 @@ Future<int> _flutterTest({
483530
if (event is ExitTestEvent) {
484531
if (completer.isCompleted) return;
485532
subscription.cancel();
533+
sigintWatchSubscription.cancel();
534+
486535
completer.complete(
487536
event.exitCode == ExitCode.success.code
488537
? ExitCode.success.code
@@ -506,6 +555,10 @@ String? _topGroupName(Test test, Map<int, TestGroup> groups) => test.groupIDs
506555
.map((groupID) => groups[groupID]?.name)
507556
.firstWhereOrNull((groupName) => groupName?.isNotEmpty ?? false);
508557

558+
Future<void> _cleanupOptimizerFile(String cwd) async => File(
559+
p.join(cwd, 'test', _testOptimizerFileName),
560+
).delete().ignore();
561+
509562
final int _lineLength = () {
510563
try {
511564
return stdout.terminalColumns;

test/src/cli/flutter_cli_test.dart

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,53 @@ void main() {
317317
stderrLogs = [];
318318
});
319319

320+
test('cleanup the .test_optimizer file when SIGINT is emitted', () async {
321+
final streamController = StreamController<ProcessSignal>();
322+
await ProcessSignalOverrides.runZoned(
323+
() async {
324+
final tempDirectory = Directory.systemTemp.createTempSync();
325+
addTearDown(() => tempDirectory.deleteSync(recursive: true));
326+
327+
final updatedVars = <String, dynamic>{
328+
'package-root': tempDirectory.path,
329+
'foo': 'bar',
330+
};
331+
332+
File(p.join(tempDirectory.path, 'pubspec.yaml')).createSync();
333+
Directory(p.join(tempDirectory.path, 'test')).createSync();
334+
when(
335+
() => hooks.preGen(
336+
vars: any(named: 'vars'),
337+
onVarsChanged: any(named: 'onVarsChanged'),
338+
workingDirectory: any(named: 'workingDirectory'),
339+
),
340+
).thenAnswer((invocation) async {
341+
(invocation.namedArguments[#onVarsChanged] as void Function(
342+
Map<String, dynamic> vars,
343+
))
344+
.call(updatedVars);
345+
});
346+
ProcessSignalOverrides.current?.addSIGINT();
347+
await Flutter.test(
348+
cwd: tempDirectory.path,
349+
optimizePerformance: true,
350+
stdout: stdoutLogs.add,
351+
stderr: stderrLogs.add,
352+
logger: logger,
353+
buildGenerator: generatorBuilder(),
354+
);
355+
final filePath = p.join(
356+
tempDirectory.path,
357+
'test',
358+
'.test_optimizer.dart',
359+
);
360+
final testOptimizerFile = File(filePath);
361+
expect(testOptimizerFile.existsSync(), isFalse);
362+
},
363+
sigintStream: streamController.stream,
364+
);
365+
});
366+
320367
test('throws when pubspec not found', () async {
321368
await expectLater(
322369
() => Flutter.test(cwd: Directory.systemTemp.path, logger: logger),

0 commit comments

Comments
 (0)