[flutter_plugin_tools] Build gtest unit tests (#4492)

This commit is contained in:
stuartmorgan
2021-11-14 21:26:05 -05:00
committed by GitHub
parent d7f8fc267f
commit f4546c0791
5 changed files with 324 additions and 40 deletions

View File

@ -5,6 +5,7 @@
import 'package:file/file.dart';
import 'package:platform/platform.dart';
import 'common/cmake.dart';
import 'common/core.dart';
import 'common/gradle.dart';
import 'common/package_looping_command.dart';
@ -456,8 +457,8 @@ this command.
file.basename.endsWith('_tests.exe');
}
return _runGoogleTestTests(plugin,
buildDirectoryName: 'windows', isTestBinary: isTestBinary);
return _runGoogleTestTests(plugin, 'Windows', 'Debug',
isTestBinary: isTestBinary);
}
Future<_PlatformResult> _testLinux(
@ -471,8 +472,16 @@ this command.
file.basename.endsWith('_tests');
}
return _runGoogleTestTests(plugin,
buildDirectoryName: 'linux', isTestBinary: isTestBinary);
// Since Linux uses a single-config generator, building-examples only
// generates the build files for release, so the tests have to be run in
// release mode as well.
//
// TODO(stuartmorgan): Consider adding a command to `flutter` that would
// generate build files without doing a build, and using that instead of
// relying on running build-examples. See
// https://github.com/flutter/flutter/issues/93407.
return _runGoogleTestTests(plugin, 'Linux', 'Release',
isTestBinary: isTestBinary);
}
/// Finds every file in the [buildDirectoryName] subdirectory of [plugin]'s
@ -482,38 +491,66 @@ this command.
/// The binaries are assumed to be Google Test test binaries, thus returning
/// zero for success and non-zero for failure.
Future<_PlatformResult> _runGoogleTestTests(
RepositoryPackage plugin, {
required String buildDirectoryName,
RepositoryPackage plugin,
String platformName,
String buildMode, {
required bool Function(File) isTestBinary,
}) async {
final List<File> testBinaries = <File>[];
bool hasMissingBuild = false;
bool buildFailed = false;
for (final RepositoryPackage example in plugin.getExamples()) {
final Directory buildDir = example.directory
.childDirectory('build')
.childDirectory(buildDirectoryName);
if (!buildDir.existsSync()) {
final CMakeProject project = CMakeProject(example.directory,
buildMode: buildMode,
processRunner: processRunner,
platform: platform);
if (!project.isConfigured()) {
printError('ERROR: Run "flutter build" on ${example.displayName}, '
'or run this tool\'s "build-examples" command, for the target '
'platform before executing tests.');
hasMissingBuild = true;
continue;
}
testBinaries.addAll(buildDir
// By repository convention, example projects create an aggregate target
// called 'unit_tests' that builds all unit tests (usually just an alias
// for a specific test target).
final int exitCode = await project.runBuild('unit_tests');
if (exitCode != 0) {
printError('${example.displayName} unit tests failed to build.');
buildFailed = true;
}
testBinaries.addAll(project.buildDirectory
.listSync(recursive: true)
.whereType<File>()
.where(isTestBinary)
.where((File file) {
// Only run the release build of the unit tests, to avoid running the
// same tests multiple times. Release is used rather than debug since
// `build-examples` builds release versions.
// Only run the `buildMode` build of the unit tests, to avoid running
// the same tests multiple times.
final List<String> components = path.split(file.path);
return components.contains('release') || components.contains('Release');
return components.contains(buildMode) ||
components.contains(buildMode.toLowerCase());
}));
}
if (hasMissingBuild) {
return _PlatformResult(RunState.failed,
error: 'Examples must be built before testing.');
}
if (buildFailed) {
return _PlatformResult(RunState.failed,
error: 'Failed to build $platformName unit tests.');
}
if (testBinaries.isEmpty) {
final String binaryExtension = platform.isWindows ? '.exe' : '';
printError(
'No test binaries found. At least one *_test(s)$binaryExtension '
'binary should be built by the example(s)');
return _PlatformResult(RunState.failed,
error: 'No $buildDirectoryName unit tests found');
error: 'No $platformName unit tests found');
}
bool passing = true;