From 60d5c8abc5d362c2fc57d5623a58ca68cf836738 Mon Sep 17 00:00:00 2001
From: Elias Yishak <42216813+eliasyishak@users.noreply.github.com>
Date: Wed, 29 Nov 2023 12:42:52 -0500
Subject: [PATCH] Migration for the `sendTiming` events for
`package:unified_analytics` (#138896)
Related to tracker issue:
- https://github.com/flutter/flutter/issues/128251
The image above shows all of the instances where we have `sendTiming`. All of the call sites have been updated to use the new `Event.timing` event from `package:unified_analytics`.
---
.../flutter_tools/lib/src/android/gradle.dart | 32 +-
.../lib/src/commands/packages.dart | 23 +-
packages/flutter_tools/lib/src/ios/mac.dart | 8 +-
.../lib/src/isolated/resident_web_runner.dart | 5 +
.../lib/src/linux/build_linux.dart | 18 +-
.../lib/src/macos/build_macos.dart | 10 +-
packages/flutter_tools/lib/src/run_hot.dart | 13 +-
.../lib/src/runner/flutter_command.dart | 18 +-
.../src/runner/flutter_command_runner.dart | 6 +
.../flutter_tools/lib/src/web/compile.dart | 8 +-
.../lib/src/windows/build_windows.dart | 18 +-
packages/flutter_tools/pubspec.yaml | 8 +-
.../hermetic/build_ipa_test.dart | 10 +
.../hermetic/build_linux_test.dart | 34 +-
.../hermetic/build_macos_test.dart | 18 +
.../hermetic/build_windows_test.dart | 50 ++
.../commands.shard/hermetic/config_test.dart | 14 +-
.../permeable/packages_test.dart | 16 +
.../android/android_gradle_builder_test.dart | 46 +-
.../test/general.shard/hot_test.dart | 562 +++++++++++-------
.../ios_device_start_nonprebuilt_test.dart | 17 +-
.../general.shard/resident_runner_test.dart | 8 +-
.../resident_web_runner_test.dart | 14 +
.../runner/flutter_command_runner_test.dart | 23 +-
.../runner/flutter_command_test.dart | 54 +-
.../general.shard/web/compile_web_test.dart | 11 +-
packages/flutter_tools/test/src/common.dart | 36 ++
27 files changed, 806 insertions(+), 274 deletions(-)
diff --git a/packages/flutter_tools/lib/src/android/gradle.dart b/packages/flutter_tools/lib/src/android/gradle.dart
index 1a54700be4..50f5ffcd96 100644
--- a/packages/flutter_tools/lib/src/android/gradle.dart
+++ b/packages/flutter_tools/lib/src/android/gradle.dart
@@ -490,7 +490,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
status.stop();
}
- _usage.sendTiming('build', 'gradle', sw.elapsed);
+ final Duration elapsedDuration = sw.elapsed;
+ _usage.sendTiming('build', 'gradle', elapsedDuration);
+ _analytics.send(Event.timing(
+ workflow: 'build',
+ variableName: 'gradle',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
if (exitCode != 0) {
if (detectedGradleError == null) {
@@ -757,7 +763,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
} finally {
status.stop();
}
- _usage.sendTiming('build', 'gradle-aar', sw.elapsed);
+ final Duration elapsedDuration = sw.elapsed;
+ _usage.sendTiming('build', 'gradle-aar', elapsedDuration);
+ _analytics.send(Event.timing(
+ workflow: 'build',
+ variableName: 'gradle-aar',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
if (result.exitCode != 0) {
_logger.printStatus(result.stdout, wrap: false);
@@ -792,7 +804,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
project: project,
);
- _usage.sendTiming('print', 'android build variants', sw.elapsed);
+ final Duration elapsedDuration = sw.elapsed;
+ _usage.sendTiming('print', 'android build variants', elapsedDuration);
+ _analytics.send(Event.timing(
+ workflow: 'print',
+ variableName: 'android build variants',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
if (result.exitCode != 0) {
_logger.printStatus(result.stdout, wrap: false);
@@ -828,7 +846,13 @@ class AndroidGradleBuilder implements AndroidBuilder {
options: ['-q', '-PoutputPath=$outputPath'],
project: project,
);
- _usage.sendTiming('outputs', 'app link settings', sw.elapsed);
+ final Duration elapsedDuration = sw.elapsed;
+ _usage.sendTiming('outputs', 'app link settings', elapsedDuration);
+ _analytics.send(Event.timing(
+ workflow: 'outputs',
+ variableName: 'app link settings',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
if (result.exitCode != 0) {
_logger.printStatus(result.stdout, wrap: false);
diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart
index eb25fc1a56..bae2f4fd7e 100644
--- a/packages/flutter_tools/lib/src/commands/packages.dart
+++ b/packages/flutter_tools/lib/src/commands/packages.dart
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'package:args/args.dart';
+import 'package:unified_analytics/unified_analytics.dart';
import '../base/common.dart';
import '../base/os.dart';
@@ -298,7 +299,7 @@ class PackagesGetCommand extends FlutterCommand {
processManager: globals.processManager,
platform: globals.platform,
usage: globals.flutterUsage,
- analytics: globals.analytics,
+ analytics: analytics,
projectDir: rootProject.directory,
generateDartPluginRegistry: true,
);
@@ -319,7 +320,7 @@ class PackagesGetCommand extends FlutterCommand {
processManager: globals.processManager,
platform: globals.platform,
usage: globals.flutterUsage,
- analytics: globals.analytics,
+ analytics: analytics,
projectDir: rootProject.directory,
generateDartPluginRegistry: true,
);
@@ -354,10 +355,24 @@ class PackagesGetCommand extends FlutterCommand {
command: name,
touchesPackageConfig: !(isHelp || dryRun),
);
- globals.flutterUsage.sendTiming('pub', 'get', timer.elapsed, label: 'success');
+ final Duration elapsedDuration = timer.elapsed;
+ globals.flutterUsage.sendTiming('pub', 'get', elapsedDuration, label: 'success');
+ analytics.send(Event.timing(
+ workflow: 'pub',
+ variableName: 'get',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ label: 'success'
+ ));
// Not limiting to catching Exception because the exception is rethrown.
} catch (_) { // ignore: avoid_catches_without_on_clauses
- globals.flutterUsage.sendTiming('pub', 'get', timer.elapsed, label: 'failure');
+ final Duration elapsedDuration = timer.elapsed;
+ globals.flutterUsage.sendTiming('pub', 'get', elapsedDuration, label: 'failure');
+ analytics.send(Event.timing(
+ workflow: 'pub',
+ variableName: 'get',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ label: 'failure'
+ ));
rethrow;
}
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index 175c7c3172..f6a05320ba 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -419,7 +419,13 @@ Future buildXcodeProject({
'Xcode ${xcodeBuildActionToString(buildAction)} done.'.padRight(kDefaultStatusPadding + 1)
+ getElapsedAsSeconds(sw.elapsed).padLeft(5),
);
- globals.flutterUsage.sendTiming(xcodeBuildActionToString(buildAction), 'xcode-ios', Duration(milliseconds: sw.elapsedMilliseconds));
+ final Duration elapsedDuration = sw.elapsed;
+ globals.flutterUsage.sendTiming(xcodeBuildActionToString(buildAction), 'xcode-ios', elapsedDuration);
+ globals.analytics.send(Event.timing(
+ workflow: xcodeBuildActionToString(buildAction),
+ variableName: 'xcode-ios',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
if (tempDir.existsSync()) {
// Display additional warning and error message from xcresult bundle.
diff --git a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
index d5a874325a..b3c0682db7 100644
--- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
+++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
@@ -452,6 +452,11 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive).
// Don't track restart times for dart2js builds or web-server devices.
if (debuggingOptions.buildInfo.isDebug && deviceIsDebuggable) {
_usage.sendTiming('hot', 'web-incremental-restart', elapsed);
+ _analytics.send(Event.timing(
+ workflow: 'hot',
+ variableName: 'web-incremental-restart',
+ elapsedMilliseconds: elapsed.inMilliseconds,
+ ));
final String sdkName = await device!.device!.sdkNameAndVersion;
HotEvent(
'restart',
diff --git a/packages/flutter_tools/lib/src/linux/build_linux.dart b/packages/flutter_tools/lib/src/linux/build_linux.dart
index 1bcf07361f..808130a24f 100644
--- a/packages/flutter_tools/lib/src/linux/build_linux.dart
+++ b/packages/flutter_tools/lib/src/linux/build_linux.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'package:unified_analytics/unified_analytics.dart';
+
import '../artifacts.dart';
import '../base/analyze_size.dart';
import '../base/common.dart';
@@ -155,7 +157,13 @@ Future _runCmake(String buildModeName, Directory sourceDir, Directory buil
if (result != 0) {
throwToolExit('Unable to generate build files');
}
- globals.flutterUsage.sendTiming('build', 'cmake-linux', Duration(milliseconds: sw.elapsedMilliseconds));
+ final Duration elapsedDuration = sw.elapsed;
+ globals.flutterUsage.sendTiming('build', 'cmake-linux', elapsedDuration);
+ globals.analytics.send(Event.timing(
+ workflow: 'build',
+ variableName: 'cmake-linux',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
}
Future _runBuild(Directory buildDir) async {
@@ -185,5 +193,11 @@ Future _runBuild(Directory buildDir) async {
if (result != 0) {
throwToolExit('Build process failed');
}
- globals.flutterUsage.sendTiming('build', 'linux-ninja', Duration(milliseconds: sw.elapsedMilliseconds));
+ final Duration elapsedDuration = sw.elapsed;
+ globals.flutterUsage.sendTiming('build', 'linux-ninja', elapsedDuration);
+ globals.analytics.send(Event.timing(
+ workflow: 'build',
+ variableName: 'linux-ninja',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
}
diff --git a/packages/flutter_tools/lib/src/macos/build_macos.dart b/packages/flutter_tools/lib/src/macos/build_macos.dart
index 4161bef7f4..40e2d52430 100644
--- a/packages/flutter_tools/lib/src/macos/build_macos.dart
+++ b/packages/flutter_tools/lib/src/macos/build_macos.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'package:unified_analytics/unified_analytics.dart';
+
import '../base/analyze_size.dart';
import '../base/common.dart';
import '../base/file_system.dart';
@@ -160,7 +162,13 @@ Future buildMacOS({
throwToolExit('Build process failed');
}
await _writeCodeSizeAnalysis(buildInfo, sizeAnalyzer);
- globals.flutterUsage.sendTiming('build', 'xcode-macos', Duration(milliseconds: sw.elapsedMilliseconds));
+ final Duration elapsedDuration = sw.elapsed;
+ globals.flutterUsage.sendTiming('build', 'xcode-macos', elapsedDuration);
+ globals.analytics.send(Event.timing(
+ workflow: 'build',
+ variableName: 'xcode-macos',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
}
/// Performs a size analysis of the AOT snapshot and writes to an analysis file, if configured.
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index 939f14ee2d..117e0f389c 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -713,7 +713,13 @@ class HotRunner extends ResidentRunner {
restartTimer.elapsed.inMilliseconds);
// Send timing analytics.
- globals.flutterUsage.sendTiming('hot', 'restart', restartTimer.elapsed);
+ final Duration elapsedDuration = restartTimer.elapsed;
+ globals.flutterUsage.sendTiming('hot', 'restart', elapsedDuration);
+ _analytics.send(Event.timing(
+ workflow: 'hot',
+ variableName: 'restart',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
// Toggle the main dill name after successfully uploading.
_swap =! _swap;
@@ -1112,6 +1118,11 @@ class HotRunner extends ResidentRunner {
// Only report timings if we reloaded a single view without any errors.
if ((reassembleResult.reassembleViews.length == 1) && !reassembleResult.failedReassemble && shouldReportReloadTime) {
globals.flutterUsage.sendTiming('hot', 'reload', reloadDuration);
+ _analytics.send(Event.timing(
+ workflow: 'hot',
+ variableName: 'reload',
+ elapsedMilliseconds: reloadDuration.inMilliseconds,
+ ));
}
return OperationResult(
reassembleResult.failedReassemble ? 1 : OperationResult.ok.code,
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart
index ac5b9e3862..e1509a3ddb 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart
@@ -1634,16 +1634,26 @@ abstract class FlutterCommand extends Command {
final String label = labels
.where((String? label) => label != null && !_isBlank(label))
.join('-');
+
+ // If the command provides its own end time, use it. Otherwise report
+ // the duration of the entire execution.
+ final Duration elapsedDuration = (commandResult.endTimeOverride ?? endTime).difference(startTime);
globals.flutterUsage.sendTiming(
'flutter',
name,
- // If the command provides its own end time, use it. Otherwise report
- // the duration of the entire execution.
- (commandResult.endTimeOverride ?? endTime).difference(startTime),
+ elapsedDuration,
// Report in the form of `success-[parameter1-parameter2]`, all of which
// can be null if the command doesn't provide a FlutterCommandResult.
label: label == '' ? null : label,
);
+ analytics.send(Event.timing(
+ workflow: 'flutter',
+ variableName: name,
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ // Report in the form of `success-[parameter1-parameter2]`, all of which
+ // can be null if the command doesn't provide a FlutterCommandResult.
+ label: label == '' ? null : label,
+ ));
}
/// Perform validation then call [runCommand] to execute the command.
@@ -1707,7 +1717,7 @@ Run 'flutter -h' (or 'flutter -h') for available flutter commands and
processManager: globals.processManager,
platform: globals.platform,
usage: globals.flutterUsage,
- analytics: globals.analytics,
+ analytics: analytics,
projectDir: project.directory,
generateDartPluginRegistry: true,
);
diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
index 7994f3af89..dadad881bc 100644
--- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
+++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart
@@ -6,6 +6,7 @@ import 'package:args/args.dart';
import 'package:args/command_runner.dart';
import 'package:completion/completion.dart';
import 'package:file/file.dart';
+import 'package:unified_analytics/unified_analytics.dart';
import '../artifacts.dart';
import '../base/common.dart';
@@ -329,6 +330,11 @@ class FlutterCommandRunner extends CommandRunner {
if ((topLevelResults[FlutterGlobalOptions.kVersionFlag] as bool?) ?? false) {
globals.flutterUsage.sendCommand(FlutterGlobalOptions.kVersionFlag);
+ globals.analytics.send(Event.flutterCommandResult(
+ commandPath: 'version',
+ result: 'success',
+ commandHasTerminal: globals.stdio.hasTerminal,
+ ));
final FlutterVersion version = globals.flutterVersion.fetchTagsAndGetVersion(
clock: globals.systemClock,
);
diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart
index 93629a7942..9fb7073ec0 100644
--- a/packages/flutter_tools/lib/src/web/compile.dart
+++ b/packages/flutter_tools/lib/src/web/compile.dart
@@ -150,11 +150,17 @@ class WebBuilder {
settings: buildSettingsString,
));
+ final Duration elapsedDuration = sw.elapsed;
_flutterUsage.sendTiming(
'build',
compilerConfig.isWasm ? 'dart2wasm' : 'dart2js',
- Duration(milliseconds: sw.elapsedMilliseconds),
+ elapsedDuration,
);
+ _analytics.send(Event.timing(
+ workflow: 'build',
+ variableName: compilerConfig.isWasm ? 'dart2wasm' : 'dart2js',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
}
}
diff --git a/packages/flutter_tools/lib/src/windows/build_windows.dart b/packages/flutter_tools/lib/src/windows/build_windows.dart
index 2a4af0408a..eed8ef17d4 100644
--- a/packages/flutter_tools/lib/src/windows/build_windows.dart
+++ b/packages/flutter_tools/lib/src/windows/build_windows.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'package:unified_analytics/unified_analytics.dart';
+
import '../artifacts.dart';
import '../base/analyze_size.dart';
import '../base/common.dart';
@@ -202,7 +204,13 @@ Future _runCmakeGeneration({
if (result != 0) {
throwToolExit('Unable to generate build files');
}
- globals.flutterUsage.sendTiming('build', 'windows-cmake-generation', Duration(milliseconds: sw.elapsedMilliseconds));
+ final Duration elapsedDuration = sw.elapsed;
+ globals.flutterUsage.sendTiming('build', 'windows-cmake-generation', elapsedDuration);
+ globals.analytics.send(Event.timing(
+ workflow: 'build',
+ variableName: 'windows-cmake-generation',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
}
Future _runBuild(
@@ -253,7 +261,13 @@ Future _runBuild(
if (result != 0) {
throwToolExit('Build process failed.');
}
- globals.flutterUsage.sendTiming('build', 'windows-cmake-build', Duration(milliseconds: sw.elapsedMilliseconds));
+ final Duration elapsedDuration = sw.elapsed;
+ globals.flutterUsage.sendTiming('build', 'windows-cmake-build', elapsedDuration);
+ globals.analytics.send(Event.timing(
+ workflow: 'build',
+ variableName: 'windows-cmake-build',
+ elapsedMilliseconds: elapsedDuration.inMilliseconds,
+ ));
}
/// Writes the generated CMake file with the configuration for the given build.
diff --git a/packages/flutter_tools/pubspec.yaml b/packages/flutter_tools/pubspec.yaml
index cdc8f8084e..3a25909025 100644
--- a/packages/flutter_tools/pubspec.yaml
+++ b/packages/flutter_tools/pubspec.yaml
@@ -48,7 +48,7 @@ dependencies:
http_multi_server: 3.2.1
convert: 3.1.1
async: 2.11.0
- unified_analytics: 5.5.0
+ unified_analytics: 5.6.0
cli_config: 0.1.2
graphs: 2.3.1
@@ -69,7 +69,7 @@ dependencies:
analyzer: 6.3.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
boolean_selector: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
built_collection: 5.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- built_value: 8.7.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ built_value: 8.8.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
csslib: 1.0.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
dap: 1.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -91,7 +91,7 @@ dependencies:
source_map_stack_trace: 2.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_maps: 0.10.12 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
source_span: 1.10.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
- sse: 4.1.3 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
+ sse: 4.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
string_scanner: 1.2.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
sync_http: 0.3.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
term_glyph: 1.2.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
@@ -115,4 +115,4 @@ dartdoc:
# Exclude this package from the hosted API docs.
nodoc: true
-# PUBSPEC CHECKSUM: e59e
+# PUBSPEC CHECKSUM: b1a1
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart
index 9c71896457..dd59cc4b24 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_ipa_test.dart
@@ -19,6 +19,7 @@ import 'package:flutter_tools/src/ios/plist_parser.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:test/fake.dart';
+import 'package:unified_analytics/unified_analytics.dart';
import '../../general.shard/ios/xcresult_test_data.dart';
import '../../src/common.dart';
@@ -78,6 +79,7 @@ void main() {
late FakePlistUtils plistUtils;
late BufferLogger logger;
late Artifacts artifacts;
+ late FakeAnalytics fakeAnalytics;
setUpAll(() {
Cache.disableLocking();
@@ -94,6 +96,10 @@ void main() {
processManager: fakeProcessManager,
);
plistUtils = FakePlistUtils();
+ fakeAnalytics = getInitializedFakeAnalyticsInstance(
+ fs: fileSystem,
+ fakeFlutterVersion: FakeFlutterVersion(),
+ );
});
// Sets up the minimal mock project files necessary to look like a Flutter project.
@@ -794,6 +800,9 @@ void main() {
const TestUsageEvent('code-size-analysis', 'ios'),
));
expect(fakeProcessManager, hasNoRemainingExpectations);
+ expect(fakeAnalytics.sentEvents, contains(
+ Event.codeSizeAnalysis(platform: 'ios')
+ ));
}, overrides: {
FileSystem: () => fileSystem,
Logger: () => logger,
@@ -801,6 +810,7 @@ void main() {
Platform: () => macosPlatform,
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: macosPlatform),
Usage: () => usage,
+ Analytics: () => fakeAnalytics,
XcodeProjectInterpreter: () => FakeXcodeProjectInterpreterWithBuildSettings(),
});
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_linux_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_linux_test.dart
index ec3bc880dd..8cae50d8ab 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_linux_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_linux_test.dart
@@ -21,6 +21,7 @@ import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:test/fake.dart';
+import 'package:unified_analytics/unified_analytics.dart';
import '../../src/common.dart';
import '../../src/context.dart';
@@ -48,12 +49,13 @@ void main() {
Cache.disableLocking();
});
- late FileSystem fileSystem;
+ late MemoryFileSystem fileSystem;
late FakeProcessManager processManager;
late ProcessUtils processUtils;
late Logger logger;
late TestUsage usage;
late Artifacts artifacts;
+ late FakeAnalytics fakeAnalytics;
setUp(() {
fileSystem = MemoryFileSystem.test();
@@ -66,6 +68,10 @@ void main() {
logger: logger,
processManager: processManager,
);
+ fakeAnalytics = getInitializedFakeAnalyticsInstance(
+ fs: fileSystem,
+ fakeFlutterVersion: FakeFlutterVersion(),
+ );
});
// Creates the mock files necessary to look like a Flutter project.
@@ -209,12 +215,30 @@ void main() {
const ['build', 'linux', '--no-pub']
);
expect(fileSystem.file('linux/flutter/ephemeral/generated_config.cmake'), exists);
+
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'build',
+ variableName: 'cmake-linux',
+ ),
+ true,
+ );
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'build',
+ variableName: 'linux-ninja',
+ ),
+ true,
+ );
}, overrides: {
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
Platform: () => linuxPlatform,
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
OperatingSystemUtils: () => FakeOperatingSystemUtils(),
+ Analytics: () => fakeAnalytics,
});
testUsingContext('Handles missing cmake', () async {
@@ -701,6 +725,9 @@ set(BINARY_NAME "fizz_bar")
expect(usage.events, contains(
const TestUsageEvent('code-size-analysis', 'linux'),
));
+ expect(fakeAnalytics.sentEvents, contains(
+ Event.codeSizeAnalysis(platform: 'linux')
+ ));
}, overrides: {
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
@@ -708,6 +735,7 @@ set(BINARY_NAME "fizz_bar")
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
Usage: () => usage,
OperatingSystemUtils: () => FakeOperatingSystemUtils(),
+ Analytics: () => fakeAnalytics,
});
testUsingContext('Linux on ARM64 build --release passes, and check if the LinuxBuildDirectory for arm64 can be referenced correctly by using analytics', () async {
@@ -754,6 +782,9 @@ set(BINARY_NAME "fizz_bar")
expect(usage.events, contains(
const TestUsageEvent('code-size-analysis', 'linux'),
));
+ expect(fakeAnalytics.sentEvents, contains(
+ Event.codeSizeAnalysis(platform: 'linux')
+ ));
}, overrides: {
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
@@ -761,6 +792,7 @@ set(BINARY_NAME "fizz_bar")
FeatureFlags: () => TestFeatureFlags(isLinuxEnabled: true),
Usage: () => usage,
OperatingSystemUtils: () => CustomFakeOperatingSystemUtils(hostPlatform: HostPlatform.linux_arm64),
+ Analytics: () => fakeAnalytics,
});
}
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_macos_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_macos_test.dart
index 172b75f272..2cd9163b5e 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_macos_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_macos_test.dart
@@ -20,6 +20,7 @@ import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/ios/xcodeproj.dart';
import 'package:flutter_tools/src/project.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
+import 'package:unified_analytics/unified_analytics.dart';
import '../../src/common.dart';
import '../../src/context.dart';
@@ -70,6 +71,7 @@ void main() {
late BufferLogger logger;
late XcodeProjectInterpreter xcodeProjectInterpreter;
late Artifacts artifacts;
+ late FakeAnalytics fakeAnalytics;
setUpAll(() {
Cache.disableLocking();
@@ -86,6 +88,10 @@ void main() {
processManager: fakeProcessManager,
);
xcodeProjectInterpreter = FakeXcodeProjectInterpreter();
+ fakeAnalytics = getInitializedFakeAnalyticsInstance(
+ fs: fileSystem,
+ fakeFlutterVersion: FakeFlutterVersion(),
+ );
});
// Sets up the minimal mock project files necessary to look like a Flutter project.
@@ -194,11 +200,21 @@ STDERR STUFF
await createTestCommandRunner(command).run(
const ['build', 'macos', '--no-pub']
);
+
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'build',
+ variableName: 'xcode-macos',
+ ),
+ true,
+ );
}, overrides: {
Platform: () => macosPlatform,
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
+ Analytics: () => fakeAnalytics,
});
testUsingContext('macOS build fails on non-macOS platform', () async {
@@ -594,6 +610,7 @@ STDERR STUFF
expect(usage.events, contains(
const TestUsageEvent('code-size-analysis', 'macos'),
));
+ expect(fakeAnalytics.sentEvents, contains(Event.codeSizeAnalysis(platform: 'macos')));
}, overrides: {
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.list([
@@ -618,5 +635,6 @@ STDERR STUFF
FeatureFlags: () => TestFeatureFlags(isMacOSEnabled: true),
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: macosPlatform),
Usage: () => usage,
+ Analytics: () => fakeAnalytics,
});
}
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_windows_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_windows_test.dart
index ec80512529..79fb6dee1f 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/build_windows_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/build_windows_test.dart
@@ -13,6 +13,7 @@ import 'package:flutter_tools/src/features.dart';
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/windows/visual_studio.dart';
import 'package:test/fake.dart';
+import 'package:unified_analytics/unified_analytics.dart';
import '../../src/common.dart';
import '../../src/context.dart';
@@ -45,6 +46,7 @@ void main() {
late FileSystem fileSystem;
late ProcessManager processManager;
late TestUsage usage;
+ late FakeAnalytics fakeAnalytics;
setUpAll(() {
Cache.disableLocking();
@@ -55,6 +57,10 @@ void main() {
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
Cache.flutterRoot = flutterRoot;
usage = TestUsage();
+ fakeAnalytics = getInitializedFakeAnalyticsInstance(
+ fs: fileSystem,
+ fakeFlutterVersion: FakeFlutterVersion(),
+ );
});
// Creates the mock files necessary to look like a Flutter project.
@@ -209,6 +215,46 @@ void main() {
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
});
+ testUsingContext('Windows build sends timing events', () async {
+ final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
+ final BuildWindowsCommand command = BuildWindowsCommand(logger: BufferLogger.test())
+ ..visualStudioOverride = fakeVisualStudio;
+ setUpMockProjectFilesForBuild();
+
+ processManager = FakeProcessManager.list([
+ cmakeGenerationCommand(),
+ buildCommand('Release'),
+ ]);
+
+ await createTestCommandRunner(command).run(
+ const ['windows', '--no-pub']
+ );
+
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'build',
+ variableName: 'windows-cmake-generation',
+ ),
+ true,
+ );
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'build',
+ variableName: 'windows-cmake-build',
+ ),
+ true,
+ );
+ }, overrides: {
+ FileSystem: () => fileSystem,
+ ProcessManager: () => processManager,
+ Platform: () => windowsPlatform,
+ FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
+ Analytics: () => fakeAnalytics,
+ });
+
+
testUsingContext('Windows build extracts errors from stdout', () async {
final FakeVisualStudio fakeVisualStudio = FakeVisualStudio();
final BuildWindowsCommand command = BuildWindowsCommand(logger: BufferLogger.test())
@@ -929,6 +975,9 @@ if %errorlevel% neq 0 goto :VCEnd
expect(usage.events, contains(
const TestUsageEvent('code-size-analysis', 'windows'),
));
+ expect(fakeAnalytics.sentEvents, contains(
+ Event.codeSizeAnalysis(platform: 'windows')
+ ));
}, overrides: {
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
FileSystem: () => fileSystem,
@@ -936,6 +985,7 @@ if %errorlevel% neq 0 goto :VCEnd
Platform: () => windowsPlatform,
FileSystemUtils: () => FileSystemUtils(fileSystem: fileSystem, platform: windowsPlatform),
Usage: () => usage,
+ Analytics: () => fakeAnalytics,
});
// Confirms that running for Windows in a directory with a
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/config_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/config_test.dart
index 4f98a5b370..88eea7f2a0 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/config_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/config_test.dart
@@ -5,6 +5,7 @@
import 'dart:convert';
import 'package:args/command_runner.dart';
+import 'package:file/memory.dart';
import 'package:flutter_tools/src/android/android_sdk.dart';
import 'package:flutter_tools/src/android/android_studio.dart';
import 'package:flutter_tools/src/android/java.dart';
@@ -17,10 +18,11 @@ import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/reporting/reporting.dart';
import 'package:flutter_tools/src/version.dart';
import 'package:test/fake.dart';
+import 'package:unified_analytics/unified_analytics.dart';
import '../../src/common.dart';
import '../../src/context.dart';
-import '../../src/fakes.dart';
+import '../../src/fakes.dart' as fakes;
import '../../src/test_flutter_command_runner.dart';
void main() {
@@ -29,23 +31,29 @@ void main() {
late FakeAndroidSdk fakeAndroidSdk;
late FakeFlutterVersion fakeFlutterVersion;
late TestUsage testUsage;
+ late FakeAnalytics fakeAnalytics;
setUpAll(() {
Cache.disableLocking();
});
setUp(() {
- fakeJava = FakeJava();
+ fakeJava = fakes.FakeJava();
fakeAndroidStudio = FakeAndroidStudio();
fakeAndroidSdk = FakeAndroidSdk();
fakeFlutterVersion = FakeFlutterVersion();
testUsage = TestUsage();
+ fakeAnalytics = getInitializedFakeAnalyticsInstance(
+ fs: MemoryFileSystem.test(),
+ fakeFlutterVersion: fakes.FakeFlutterVersion(),
+ );
});
void verifyNoAnalytics() {
expect(testUsage.commands, isEmpty);
expect(testUsage.events, isEmpty);
expect(testUsage.timings, isEmpty);
+ expect(fakeAnalytics.sentEvents, isEmpty);
}
group('config', () {
@@ -263,6 +271,7 @@ void main() {
]));
expect(testUsage.commands, isEmpty);
expect(testUsage.timings, isEmpty);
+ expect(fakeAnalytics.sentEvents, isEmpty);
}, overrides: {
Usage: () => testUsage,
});
@@ -285,6 +294,7 @@ void main() {
]));
expect(testUsage.commands, isEmpty);
expect(testUsage.timings, isEmpty);
+ expect(fakeAnalytics.sentEvents, isEmpty);
}, overrides: {
Usage: () => testUsage,
});
diff --git a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart
index df14535004..8b197e6a03 100644
--- a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart
+++ b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart
@@ -23,6 +23,7 @@ import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/packages.dart';
import 'package:flutter_tools/src/dart/pub.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
+import 'package:unified_analytics/unified_analytics.dart';
import '../../src/common.dart';
import '../../src/context.dart';
@@ -40,9 +41,14 @@ void main() {
Cache.disableLocking();
group('packages get/upgrade', () {
late Directory tempDir;
+ late FakeAnalytics fakeAnalytics;
setUp(() {
tempDir = globals.fs.systemTempDirectory.createTempSync('flutter_tools_packages_test.');
+ fakeAnalytics = getInitializedFakeAnalyticsInstance(
+ fs: MemoryFileSystem.test(),
+ fakeFlutterVersion: FakeFlutterVersion(),
+ );
});
tearDown(() {
@@ -220,6 +226,15 @@ void main() {
expectDependenciesResolved(projectPath);
expectZeroPluginsInjected(projectPath);
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'pub',
+ variableName: 'get',
+ label: 'success',
+ ),
+ true,
+ );
}, overrides: {
Stdio: () => mockStdio,
Pub: () => Pub.test(
@@ -231,6 +246,7 @@ void main() {
platform: globals.platform,
stdio: mockStdio,
),
+ Analytics: () => fakeAnalytics,
});
testUsingContext('get --offline fetches packages', () async {
diff --git a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
index 95a1fd6c3e..dee0bd4094 100644
--- a/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
+++ b/packages/flutter_tools/test/general.shard/android/android_gradle_builder_test.dart
@@ -145,11 +145,21 @@ void main() {
expect(
fakeAnalytics.sentEvents,
- unorderedEquals([
+ containsAll([
Event.flutterBuildInfo(label: 'app-not-using-android-x', buildType: 'gradle'),
Event.flutterBuildInfo(label: 'gradle-random-event-label-failure', buildType: 'gradle'),
]),
);
+
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'build',
+ variableName: 'gradle',
+ ),
+ true,
+ );
+
}, overrides: {
AndroidStudio: () => FakeAndroidStudio(),
});
@@ -328,7 +338,7 @@ void main() {
));
expect(testUsage.events, hasLength(4));
- expect(fakeAnalytics.sentEvents, hasLength(4));
+ expect(fakeAnalytics.sentEvents, hasLength(7));
expect(fakeAnalytics.sentEvents, contains(
Event.flutterBuildInfo(
label: 'gradle-random-event-label-failure',
@@ -431,7 +441,7 @@ void main() {
));
expect(testUsage.events, hasLength(2));
- expect(fakeAnalytics.sentEvents, hasLength(2));
+ expect(fakeAnalytics.sentEvents, hasLength(3));
expect(fakeAnalytics.sentEvents, contains(
Event.flutterBuildInfo(
label: 'gradle-random-event-label-failure',
@@ -878,8 +888,18 @@ BuildVariant: paidProfile
project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
);
expect(actual, ['freeDebug', 'paidDebug', 'freeRelease', 'paidRelease', 'freeProfile', 'paidProfile']);
+
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'print',
+ variableName: 'android build variants',
+ ),
+ true,
+ );
}, overrides: {
AndroidStudio: () => FakeAndroidStudio(),
+ Analytics: () => fakeAnalytics,
});
testUsingContext('getBuildOptions returns empty list if gradle returns error', () async {
@@ -941,10 +961,20 @@ Gradle Crashed
'freeDebug',
project: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
);
+
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'outputs',
+ variableName: 'app link settings',
+ ),
+ true,
+ );
}, overrides: {
AndroidStudio: () => FakeAndroidStudio(),
FileSystem: () => fileSystem,
ProcessManager: () => processManager,
+ Analytics: () => fakeAnalytics,
});
testUsingContext("doesn't indicate how to consume an AAR when printHowToConsumeAar is false", () async {
@@ -1010,8 +1040,18 @@ Gradle Crashed
isFalse,
);
expect(processManager, hasNoRemainingExpectations);
+
+ expect(
+ analyticsTimingEventExists(
+ sentEvents: fakeAnalytics.sentEvents,
+ workflow: 'build',
+ variableName: 'gradle-aar',
+ ),
+ true,
+ );
}, overrides: {
AndroidStudio: () => FakeAndroidStudio(),
+ Analytics: () => fakeAnalytics,
});
testUsingContext('Verbose mode for AARs includes Gradle stacktrace and sets debug log level', () async {
diff --git a/packages/flutter_tools/test/general.shard/hot_test.dart b/packages/flutter_tools/test/general.shard/hot_test.dart
index 4fad1eb422..f8e5d27c5c 100644
--- a/packages/flutter_tools/test/general.shard/hot_test.dart
+++ b/packages/flutter_tools/test/general.shard/hot_test.dart
@@ -21,7 +21,8 @@ import 'package:flutter_tools/src/resident_devtools_handler.dart';
import 'package:flutter_tools/src/resident_runner.dart';
import 'package:flutter_tools/src/run_hot.dart';
import 'package:flutter_tools/src/vmservice.dart';
-import 'package:native_assets_cli/native_assets_cli.dart' hide BuildMode, Target;
+import 'package:native_assets_cli/native_assets_cli.dart'
+ hide BuildMode, Target;
import 'package:native_assets_cli/native_assets_cli.dart' as native_assets_cli;
import 'package:package_config/package_config.dart';
import 'package:test/fake.dart';
@@ -36,84 +37,116 @@ import 'fake_native_assets_build_runner.dart';
void main() {
group('validateReloadReport', () {
testUsingContext('invalid', () async {
- expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse({
- 'type': 'ReloadReport',
- 'success': false,
- 'details': {},
- })), false);
- expect(HotRunner.validateReloadReport(vm_service.ReloadReport.parse({
- 'type': 'ReloadReport',
- 'success': false,
- 'details': {
- 'notices':