[tool] Add initial file-based command skipping (#8928)

Adds initial file-based filtering. This does not attempt to be comprehensive, just to get some low-hanging fruit, and to create a blueprint for anyone to follow in the future when adding more filtering. I expect that once this is in place, what will happen is that as we notice cases where PRs are hitting slow or flaky tests that they clearly don't need to, we can incrementally improve the filtering on demand.

Fixes https://github.com/flutter/flutter/issues/136394
This commit is contained in:
stuartmorgan-g
2025-04-18 07:19:25 -07:00
committed by GitHub
parent 4988af58c1
commit fdc1ec7c1c
19 changed files with 792 additions and 28 deletions

View File

@ -20,11 +20,12 @@ void main() {
late Directory packagesDir;
late CommandRunner<void> runner;
late RecordingProcessRunner processRunner;
late RecordingProcessRunner gitProcessRunner;
setUp(() {
mockPlatform = MockPlatform();
final GitDir gitDir;
(:packagesDir, :processRunner, gitProcessRunner: _, :gitDir) =
(:packagesDir, :processRunner, :gitProcessRunner, :gitDir) =
configureBaseCommandMocks(platform: mockPlatform);
final DartTestCommand command = DartTestCommand(
packagesDir,
@ -713,5 +714,91 @@ test_on: !vm && firefox
]),
);
});
group('file filtering', () {
test('runs command for changes to Dart source', () async {
createFakePackage('package_a', packagesDir);
gitProcessRunner.mockProcessesForExecutable['git-diff'] =
<FakeProcessInfo>[
FakeProcessInfo(MockProcess(stdout: '''
packages/package_a/foo.dart
''')),
];
final List<String> output =
await runCapturingPrint(runner, <String>['test']);
expect(
output,
containsAllInOrder(<Matcher>[
contains('Running for package_a'),
]));
});
const List<String> files = <String>[
'foo.java',
'foo.kt',
'foo.m',
'foo.swift',
'foo.c',
'foo.cc',
'foo.cpp',
'foo.h',
];
for (final String file in files) {
test('skips command for changes to non-Dart source $file', () async {
createFakePackage('package_a', packagesDir);
gitProcessRunner.mockProcessesForExecutable['git-diff'] =
<FakeProcessInfo>[
FakeProcessInfo(MockProcess(stdout: '''
packages/package_a/$file
''')),
];
final List<String> output =
await runCapturingPrint(runner, <String>['test']);
expect(
output,
isNot(containsAllInOrder(<Matcher>[
contains('Running for package_a'),
])));
expect(
output,
containsAllInOrder(<Matcher>[
contains('SKIPPING ALL PACKAGES'),
]));
});
}
test('skips commands if all files should be ignored', () async {
createFakePackage('package_a', packagesDir);
gitProcessRunner.mockProcessesForExecutable['git-diff'] =
<FakeProcessInfo>[
FakeProcessInfo(MockProcess(stdout: '''
README.md
CODEOWNERS
packages/package_a/CHANGELOG.md
''')),
];
final List<String> output =
await runCapturingPrint(runner, <String>['test']);
expect(
output,
isNot(containsAllInOrder(<Matcher>[
contains('Running for package_a'),
])));
expect(
output,
containsAllInOrder(<Matcher>[
contains('SKIPPING ALL PACKAGES'),
]));
});
});
});
}