Unverified Commit 33ad5bac authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Attempt to enable tool coverage redux (#35074)

parent 206d43de
......@@ -120,6 +120,19 @@ task:
container:
cpu: 4
memory: 12G
- name: tool_coverage-linux
# Only re-run tool coverage if the package itself changed.
skip: "!changesInclude('./packages/flutter_tools/**/*', '.cirrus.yml', './dev/bots/test.dart')"
env:
GCLOUD_SERVICE_ACCOUNT_KEY: ENCRYPTED[f12abe60f5045d619ef4c79b83dd1e0722a0b0b13dbea95fbe334e2db7fffbcd841a5a92da8824848b539a19afe0c9fb]
CODECOV_TOKEN: ENCRYPTED[7c76a7f8c9264f3b7f3fd63fcf186f93c62c4dfe43ec288861c2f506d456681032b89efe7b7a139c82156350ca2c752c]
SHARD: tool_coverage
test_script:
- dart --enable-asserts ./dev/bots/test.dart
- bash <(curl -s https://codecov.io/bash) -c -s ./packages/flutter_tools/coverage/ -f '*.lcov.info' -F flutter_tool
container:
cpu: 8
memory: 24G
- name: web_tests-linux
# TODO(jonahwilliams): re-enabled once we've determined causes for flakiness
allow_failures: true
......
......@@ -20,6 +20,7 @@ final String flutter = path.join(flutterRoot, 'bin', Platform.isWindows ? 'flutt
final String dart = path.join(flutterRoot, 'bin', 'cache', 'dart-sdk', 'bin', Platform.isWindows ? 'dart.exe' : 'dart');
final String pub = path.join(flutterRoot, 'bin', 'cache', 'dart-sdk', 'bin', Platform.isWindows ? 'pub.bat' : 'pub');
final String pubCache = path.join(flutterRoot, '.pub-cache');
final String toolRoot = path.join(flutterRoot, 'packages', 'flutter_tools');
final List<String> flutterTestArgs = <String>[];
final bool useFlutterTestFormatter = Platform.environment['FLUTTER_TEST_FORMATTER'] == 'true';
......@@ -30,6 +31,7 @@ const Map<String, ShardRunner> _kShards = <String, ShardRunner>{
'tests': _runTests,
'web_tests': _runWebTests,
'tool_tests': _runToolTests,
'tool_coverage': _runToolCoverage,
'build_tests': _runBuildTests,
'coverage': _runCoverage,
'integration_tests': _runIntegrationTests,
......@@ -176,6 +178,58 @@ Future<bq.BigqueryApi> _getBigqueryApi() async {
}
}
// Partition tool tests into two groups, see explanation on `_runToolCoverage`.
List<List<String>> _partitionToolTests() {
final List<String> pending = <String>[];
final String toolTestDir = path.join(toolRoot, 'test');
for (FileSystemEntity entity in Directory(toolTestDir).listSync(recursive: true)) {
if (entity is File && entity.path.endsWith('_test.dart')) {
final String relativePath = path.relative(entity.path, from: toolRoot);
pending.add(relativePath);
}
}
// Shuffle the tests to avoid giving an expensive test directory like
// integration to a single run of tests.
pending..shuffle();
final int aboutHalf = pending.length ~/ 2;
final List<String> groupA = pending.take(aboutHalf).toList();
final List<String> groupB = pending.skip(aboutHalf).toList();
return <List<String>>[groupA, groupB];
}
// Tools tests run with coverage enabled have much higher memory usage than
// our current CI infrastructure can support. We partition the tests into
// two sets and run them in separate invocations of dart to reduce peak memory
// usage. codecov.io automatically handles merging different coverage files
// together, so producing separate files is OK.
//
// See: https://github.com/flutter/flutter/issues/35025
Future<void> _runToolCoverage() async {
final List<List<String>> tests = _partitionToolTests();
// Precompile tests to speed up subsequent runs.
await runCommand(
pub,
<String>['run', 'build_runner', 'build'],
workingDirectory: toolRoot,
);
// The name of this subshard has to match the --file path provided at
// the end of this test script in `.cirrus.yml`.
const List<String> subshards = <String>['A', 'B'];
for (int i = 0; i < tests.length; i++) {
final List<String> testGroup = tests[i];
await runCommand(
dart,
<String>[path.join('tool', 'tool_coverage.dart'), '--']..addAll(testGroup),
workingDirectory: toolRoot,
environment: <String, String>{
'FLUTTER_ROOT': flutterRoot,
'SUBSHARD': subshards[i],
}
);
}
}
Future<void> _runToolTests() async {
final bq.BigqueryApi bigqueryApi = await _getBigqueryApi();
await _runSmokeTests();
......
......@@ -41,6 +41,32 @@ class CoverageCollector extends TestWatcher {
}
}
/// Collects coverage for an isolate using the given `port`.
///
/// This should be called when the code whose coverage data is being collected
/// has been run to completion so that all coverage data has been recorded.
///
/// The returned [Future] completes when the coverage is collected.
Future<void> collectCoverageIsolate(Uri observatoryUri) async {
assert(observatoryUri != null);
printTrace('collecting coverage data from $observatoryUri...');
final Map<String, dynamic> data = await collect(observatoryUri, (String libraryName) {
// If we have a specified coverage directory or could not find the package name, then
// accept all libraries.
return (coverageDirectory != null)
|| (flutterProject == null)
|| libraryName.contains(flutterProject.manifest.appName);
});
if (data == null) {
throw Exception('Failed to collect coverage.');
}
assert(data != null);
print('($observatoryUri): collected coverage data; merging...');
_addHitmap(coverage.createHitmap(data['coverage']));
print('($observatoryUri): done merging coverage data into global coverage map.');
}
/// Collects coverage for the given [Process] using the given `port`.
///
/// This should be called when the code whose coverage data is being collected
......@@ -91,7 +117,6 @@ class CoverageCollector extends TestWatcher {
coverage.Formatter formatter,
Directory coverageDirectory,
}) async {
printTrace('formating coverage data');
if (_globalHitmap == null) {
return null;
}
......
......@@ -2,7 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@Tags(<String>['create'])
// This test performs too poorly to run with coverage enabled.
@Tags(<String>['create', 'no_coverage'])
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
......
......@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Integration tests which invoke flutter instead of unit testing the code
// will not produce meaningful coverage information - we can measure coverage
// from the isolate running the test, but not from the isolate started via
// the command line process.
@Tags(<String>['no_coverage'])
import 'dart:async';
import 'dart:convert';
......
......@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Integration tests which invoke flutter instead of unit testing the code
// will not produce meaningful coverage information - we can measure coverage
// from the isolate running the test, but not from the isolate started via
// the command line process.
@Tags(<String>['no_coverage'])
import 'package:file/file.dart';
import 'package:flutter_tools/src/base/file_system.dart';
......
......@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Integration tests which invoke flutter instead of unit testing the code
// will not produce meaningful coverage information - we can measure coverage
// from the isolate running the test, but not from the isolate started via
// the command line process.
@Tags(<String>['no_coverage'])
import 'dart:async';
import 'package:file/file.dart';
......
......@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Integration tests which invoke flutter instead of unit testing the code
// will not produce meaningful coverage information - we can measure coverage
// from the isolate running the test, but not from the isolate started via
// the command line process.
@Tags(<String>['no_coverage'])
import 'package:file/file.dart';
import 'package:flutter_tools/src/base/file_system.dart';
......
......@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Integration tests which invoke flutter instead of unit testing the code
// will not produce meaningful coverage information - we can measure coverage
// from the isolate running the test, but not from the isolate started via
// the command line process.
@Tags(<String>['no_coverage'])
import 'package:file/file.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
......
......@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Integration tests which invoke flutter instead of unit testing the code
// will not produce meaningful coverage information - we can measure coverage
// from the isolate running the test, but not from the isolate started via
// the command line process.
@Tags(<String>['no_coverage'])
import 'dart:async';
import 'package:file/file.dart';
......
......@@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Integration tests which invoke flutter instead of unit testing the code
// will not produce meaningful coverage information - we can measure coverage
// from the isolate running the test, but not from the isolate started via
// the command line process.
@Tags(<String>['no_coverage'])
import 'dart:async';
import 'package:file/file.dart';
......
......@@ -18,7 +18,7 @@ import 'package:flutter_tools/src/commands/create.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
export 'package:test_api/test_api.dart' hide TypeMatcher, isInstanceOf; // Defines a 'package:test' shim.
export 'package:test_core/test_core.dart' hide TypeMatcher, isInstanceOf; // Defines a 'package:test' shim.
/// Disable both web and desktop to make testing easier. For example, prevent
/// them from showing up in the devices list if the host happens to be setup
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment