Skip to content

Commit 6ecd000

Browse files
authored
Add leak checker. (#4109)
1 parent 21eae68 commit 6ecd000

File tree

6 files changed

+206
-26
lines changed

6 files changed

+206
-26
lines changed

.github/workflows/dart.yml

Lines changed: 114 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build_runner_core/mono_pkg.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,7 @@ stages:
1313
os:
1414
- linux
1515
- windows
16+
- leak_check:
17+
- group:
18+
- command: ../tool/leak_check.sh
19+
sdk: dev
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'dart:io';
6+
7+
import 'invalidation_tester.dart';
8+
9+
/// Checks for memory leaks.
10+
///
11+
/// Runs many incremental builds, prints the average increase in memory usage
12+
/// per build.
13+
///
14+
/// Run using `tool/leak_check.sh`.
15+
void main(List<String> arguments) async {
16+
final tester = InvalidationTester(testIsRunning: false);
17+
18+
tester.sources(['a.1']);
19+
20+
tester.builder(from: '.1', to: '.2')
21+
..reads('.1')
22+
..resolvesOther('a.1')
23+
..writes('.2');
24+
25+
await tester.build();
26+
await tester.build(change: 'a.1');
27+
28+
// `.dart_tool/build_resolvers/sdk.sum` will be calculated and written if it
29+
// does not yet exist, leading to very different memory usage. Users should
30+
// run with the arg `setup` first to make sure this has happened.
31+
if (arguments.contains('setup')) return;
32+
33+
final before = ProcessInfo.currentRss;
34+
for (var i = 0; i != 5000; ++i) {
35+
await tester.build(change: 'a.1');
36+
}
37+
final after = ProcessInfo.currentRss;
38+
print((after - before) ~/ 5000);
39+
}

build_runner_core/test/invalidation/invalidation_tester.dart

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import 'package:test/test.dart';
2222
/// to the path `lib/a.dart`; all names map to the package `pkg`. "Hidden" asset
2323
/// IDs under `.dart_tool` are mapped back to the same namespace.
2424
class InvalidationTester {
25+
final bool testIsRunning;
26+
2527
/// The source assets on disk before the first build.
2628
final Set<AssetId> _sourceAssets = {};
2729

@@ -65,6 +67,8 @@ class InvalidationTester {
6567
/// Output number, for writing outputs that are different.
6668
int _outputNumber = 0;
6769

70+
InvalidationTester({this.testIsRunning = true});
71+
6872
/// Starts logging test setup.
6973
///
7074
/// Useful if test setup is random or generated.
@@ -231,11 +235,13 @@ class InvalidationTester {
231235
testingBuilderConfig: false,
232236
);
233237
final logString = log.toString();
234-
printOnFailure(
235-
'=== build log #${++_buildNumber} ===\n\n'
236-
'${_setupLog.map((l) => ' $l\n').join('')}'
237-
'${logString.trimAndIndent}',
238-
);
238+
if (testIsRunning) {
239+
printOnFailure(
240+
'=== build log #${++_buildNumber} ===\n\n'
241+
'${_setupLog.map((l) => ' $l\n').join('')}'
242+
'${logString.trimAndIndent}',
243+
);
244+
}
239245
if (_logSetup) _setupLog.clear();
240246
readerWriter = testBuildResult.readerWriter;
241247

tool/ci.sh

Lines changed: 5 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)