Skip to content

Commit

Permalink
-
Browse files Browse the repository at this point in the history
  • Loading branch information
polina-c committed Jul 30, 2023
1 parent 4b9fc6b commit c34799c
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 28 deletions.
3 changes: 3 additions & 0 deletions pkgs/leak_tracker/lib/src/leak_tracking/_object_record.dart
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,9 @@ class ObjectRecord {
);

final IdentityHashCode code;

Map<String, dynamic>? context;

final PhaseSettings phase;

/// Type of the tracked object.
Expand Down Expand Up @@ -178,5 +180,6 @@ class ObjectRecord {
context: context,
code: code,
trackedClass: trackedClass,
phase: phase.name,
);
}
15 changes: 0 additions & 15 deletions pkgs/leak_tracker/lib/src/leak_tracking/model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,6 @@ typedef LeakSummaryCallback = void Function(LeakSummary);
/// The parameter [leaks] contains details about found leaks.
typedef LeaksCallback = void Function(Leaks leaks);

enum LeakTrackingEnvironment {
test,
application,
}

/// Configuration for diagnostics.
///
/// Stacktrace and retaining path collection can seriously affect performance and memory footprint.
Expand Down Expand Up @@ -87,7 +82,6 @@ class LeakTrackingConfig {
this.leakDiagnosticConfig = const LeakDiagnosticConfig(),
this.numberOfGcCycles = defaultNumberOfGcCycles,
this.maxRequestsForRetainingPath = 10,
this.leakTrackingEnvironment = LeakTrackingEnvironment.application,
});

/// The leak tracker:
Expand All @@ -99,8 +93,6 @@ class LeakTrackingConfig {
LeakDiagnosticConfig leakDiagnosticConfig = const LeakDiagnosticConfig(),
int numberOfGcCycles = defaultNumberOfGcCycles,
int? maxRequestsForRetainingPath = 10,
LeakTrackingEnvironment leakTrackingEnvironment =
LeakTrackingEnvironment.application,
}) : this(
stdoutLeaks: false,
notifyDevTools: false,
Expand All @@ -109,15 +101,8 @@ class LeakTrackingConfig {
leakDiagnosticConfig: leakDiagnosticConfig,
numberOfGcCycles: numberOfGcCycles,
maxRequestsForRetainingPath: maxRequestsForRetainingPath,
leakTrackingEnvironment: leakTrackingEnvironment,
);

/// Environment where leak tracking is used.
///
/// Defines output format for leaks.
/// Does not affect the leak tracking process.
final LeakTrackingEnvironment leakTrackingEnvironment;

/// Number of full GC cycles, enough for a non reachable object to be GCed.
final int numberOfGcCycles;

Expand Down
27 changes: 23 additions & 4 deletions pkgs/leak_tracker/lib/src/shared/shared_model.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ class ContextKeys {
static const retainingPath = 'path';
}

enum LeakTrackingEnvironment {
test,
application,
}

enum LeakType {
/// Not disposed and garbage collected.
notDisposed,
Expand All @@ -36,6 +41,7 @@ class _JsonFields {
static const String code = 'code';
static const String time = 'time';
static const String totals = 'totals';
static const String phase = 'phase';
}

abstract class LeakProvider {
Expand Down Expand Up @@ -111,10 +117,13 @@ class Leaks {

int get total => byType.values.map((e) => e.length).sum;

String toYaml() {
String toYaml(LeakTrackingEnvironment environment) {
if (total == 0) return '';
final leaks = LeakType.values
.map((e) => LeakReport.iterableToYaml(e.name, byType[e] ?? []))
.map(
(e) => LeakReport.iterableToYaml(e.name, byType[e] ?? [],
environment: environment),
)
.join();
return '$leakTrackerYamlHeader$leaks';
}
Expand All @@ -128,6 +137,7 @@ class LeakReport {
required this.context,
required this.code,
required this.type,
required this.phase,
});

factory LeakReport.fromJson(Map<String, dynamic> json) => LeakReport(
Expand All @@ -136,6 +146,7 @@ class LeakReport {
.cast<String, dynamic>(),
code: json[_JsonFields.code],
trackedClass: json[_JsonFields.trackedClass] ?? '',
phase: json[_JsonFields.phase],
);

/// Information about the leak that can help in troubleshooting.
Expand All @@ -152,6 +163,8 @@ class LeakReport {
/// Usually [trackedClass] is expected to be a supertype of [type].
final String trackedClass;

final String? phase;

// The fields below do not need serialization as they are populated after.
String? retainingPath;
List<String>? detailedPath;
Expand All @@ -167,19 +180,25 @@ class LeakReport {
String title,
Iterable<LeakReport>? leaks, {
String indent = '',
required LeakTrackingEnvironment environment,
}) {
if (leaks == null || leaks.isEmpty) return '';

return '''$title:
$indent total: ${leaks.length}
$indent objects:
${leaks.map((e) => e.toYaml('$indent ')).join()}
${leaks.map((e) => e.toYaml('$indent ', environment)).join()}
''';
}

String toYaml(String indent) {
String toYaml(String indent, LeakTrackingEnvironment environment) {
final result = StringBuffer();
result.writeln('$indent$type:');
if (phase != null) {
final fieldName =
environment == LeakTrackingEnvironment.application ? 'phase' : 'test';
result.writeln('$indent $fieldName: $phase');
}
result.writeln('$indent identityHashCode: $code');
final theContext = context;
if (theContext != null && theContext.isNotEmpty) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

import 'dart:async';

import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:leak_tracker/leak_tracker.dart';

Expand All @@ -27,8 +26,9 @@ Future<void> testExecutable(FutureOr<void> Function() testMain) async {
if (e is! TestFailure) {
rethrow;
}
//expect(e.message, contains(test1TrackingOn));
expect(e.message, contains(test1TrackingOn));
expect(e.message!.contains(test2TrackingOff), false);
print(e.message);
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,7 @@ void setUpTestingWithLeakTracking() {
_printPlatformWarningIfNeeded();
if (!_isPlatformSupported) return;

LeakTracking.start(
config: LeakTrackingConfig.passive(
leakTrackingEnvironment: LeakTrackingEnvironment.test,
),
);
LeakTracking.start(config: LeakTrackingConfig.passive());

MemoryAllocations.instance.addListener(_flutterEventToLeakTracker);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class MockObjectTracker extends ObjectTracker {
leakDiagnosticConfig: const LeakDiagnosticConfig(),
numberOfGcCycles: 3,
maxRequestsForRetainingPath: 10,
phase: ObjectRef(const PhaseSettings()),
phase: ObjectRef(const PhaseSettings.test()),
);

final events = <Event>[];
Expand Down
3 changes: 2 additions & 1 deletion pkgs/leak_tracker_testing/lib/src/matchers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ class _IsLeakFree extends Matcher {
);
}

return mismatchDescription..add('contains leaks:\n${item.toYaml()}');
return mismatchDescription
..add('contains leaks:\n${item.toYaml(LeakTrackingEnvironment.test)}');
}

@override
Expand Down

0 comments on commit c34799c

Please sign in to comment.