| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| import 'package:file/file.dart'; |
| import 'package:file_testing/file_testing.dart'; |
| import 'package:flutter_tools/src/base/io.dart'; |
| |
| import '../src/common.dart'; |
| import 'test_utils.dart'; |
| |
| // This test file does not use [getLocalEngineArguments] because it requires |
| // multiple specific artifact output types. |
| |
| const String apkDebugMessage = 'A summary of your APK analysis can be found at: '; |
| const String iosDebugMessage = 'A summary of your iOS bundle analysis can be found at: '; |
| const String macOSDebugMessage = 'A summary of your macOS bundle analysis can be found at: '; |
| const String runDevToolsMessage = 'flutter pub global activate devtools; flutter pub global run devtools '; |
| |
| void main() { |
| testWithoutContext('--analyze-size flag produces expected output on hello_world for Android', () async { |
| final String workingDirectory = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world'); |
| final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); |
| final ProcessResult result = await processManager.run(<String>[ |
| flutterBin, |
| 'build', |
| 'apk', |
| '--analyze-size', |
| '--target-platform=android-arm64', |
| ], workingDirectory: workingDirectory); |
| |
| printOnFailure('Output of flutter build apk:'); |
| printOnFailure(result.stdout.toString()); |
| printOnFailure(result.stderr.toString()); |
| expect(result.stdout.toString(), contains('app-release.apk (total compressed)')); |
| |
| final String line = result.stdout.toString() |
| .split('\n') |
| .firstWhere((String line) => line.contains(apkDebugMessage)); |
| |
| final String outputFilePath = line.split(apkDebugMessage).last.trim(); |
| expect(fileSystem.file(fileSystem.path.join(workingDirectory, outputFilePath)), exists); |
| expect(outputFilePath, contains('.flutter-devtools')); |
| |
| final String devToolsCommand = result.stdout.toString() |
| .split('\n') |
| .firstWhere((String line) => line.contains(runDevToolsMessage)); |
| final String commandArguments = devToolsCommand.split(runDevToolsMessage).last.trim(); |
| final String relativeAppSizePath = outputFilePath.split('.flutter-devtools/').last.trim(); |
| expect(commandArguments.contains('--appSizeBase=$relativeAppSizePath'), isTrue); |
| |
| expect(result.exitCode, 0); |
| }); |
| |
| testWithoutContext('--analyze-size flag produces expected output on hello_world for iOS', () async { |
| final String workingDirectory = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world'); |
| final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); |
| final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_size_test.'); |
| final Directory codeSizeDir = tempDir.childDirectory('code size dir')..createSync(); |
| final ProcessResult result = await processManager.run(<String>[ |
| flutterBin, |
| 'build', |
| 'ios', |
| '--analyze-size', |
| '--code-size-directory=${codeSizeDir.path}', |
| '--no-codesign', |
| ], workingDirectory: workingDirectory); |
| |
| printOnFailure('Output of flutter build ios:'); |
| printOnFailure(result.stdout.toString()); |
| printOnFailure(result.stderr.toString()); |
| expect(result.stdout.toString(), contains('Dart AOT symbols accounted decompressed size')); |
| |
| final String line = result.stdout.toString() |
| .split('\n') |
| .firstWhere((String line) => line.contains(iosDebugMessage)); |
| |
| final String outputFilePath = line.split(iosDebugMessage).last.trim(); |
| expect(fileSystem.file(fileSystem.path.join(workingDirectory, outputFilePath)), exists); |
| |
| final String devToolsCommand = result.stdout.toString() |
| .split('\n') |
| .firstWhere((String line) => line.contains(runDevToolsMessage)); |
| final String commandArguments = devToolsCommand.split(runDevToolsMessage).last.trim(); |
| final String relativeAppSizePath = outputFilePath.split('.flutter-devtools/').last.trim(); |
| |
| expect(commandArguments.contains('--appSizeBase=$relativeAppSizePath'), isTrue); |
| expect(codeSizeDir.existsSync(), true); |
| expect(result.exitCode, 0); |
| tempDir.deleteSync(recursive: true); |
| }, skip: !platform.isMacOS); // [intended] iOS can only be built on macos. |
| |
| testWithoutContext('--analyze-size flag produces expected output on hello_world for macOS', () async { |
| final String workingDirectory = fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world'); |
| final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); |
| final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_size_test.'); |
| final Directory codeSizeDir = tempDir.childDirectory('code size dir')..createSync(); |
| |
| final ProcessResult configResult = await processManager.run(<String>[ |
| flutterBin, |
| 'config', |
| '--enable-macos-desktop', |
| ], workingDirectory: workingDirectory); |
| |
| printOnFailure('Output of flutter config:'); |
| printOnFailure(configResult.stdout.toString()); |
| printOnFailure(configResult.stderr.toString()); |
| |
| final ProcessResult result = await processManager.run(<String>[ |
| flutterBin, |
| 'build', |
| 'macos', |
| '--analyze-size', |
| '--code-size-directory=${codeSizeDir.path}', |
| ], workingDirectory: workingDirectory); |
| |
| printOnFailure('Output of flutter build macos:'); |
| printOnFailure(result.stdout.toString()); |
| printOnFailure(result.stderr.toString()); |
| expect(result.stdout.toString(), contains('Dart AOT symbols accounted decompressed size')); |
| |
| final String line = result.stdout.toString() |
| .split('\n') |
| .firstWhere((String line) => line.contains(macOSDebugMessage)); |
| |
| final String outputFilePath = line.split(macOSDebugMessage).last.trim(); |
| expect(fileSystem.file(fileSystem.path.join(workingDirectory, outputFilePath)), exists); |
| |
| final String devToolsCommand = result.stdout.toString() |
| .split('\n') |
| .firstWhere((String line) => line.contains(runDevToolsMessage)); |
| final String commandArguments = devToolsCommand.split(runDevToolsMessage).last.trim(); |
| final String relativeAppSizePath = outputFilePath.split('.flutter-devtools/').last.trim(); |
| |
| expect(commandArguments.contains('--appSizeBase=$relativeAppSizePath'), isTrue); |
| expect(codeSizeDir.existsSync(), true); |
| expect(result.exitCode, 0); |
| tempDir.deleteSync(recursive: true); |
| }, skip: !platform.isMacOS); // [intended] this is a macos only test. |
| |
| testWithoutContext('--analyze-size is only supported in release mode', () async { |
| final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); |
| final ProcessResult result = await processManager.run(<String>[ |
| flutterBin, |
| 'build', |
| 'apk', |
| '--analyze-size', |
| '--target-platform=android-arm64', |
| '--debug', |
| ], workingDirectory: fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world')); |
| |
| printOnFailure('Output of flutter build apk:'); |
| printOnFailure(result.stdout.toString()); |
| printOnFailure(result.stderr.toString()); |
| expect(result.stderr.toString(), contains('"--analyze-size" can only be used on release builds')); |
| |
| expect(result.exitCode, 1); |
| }); |
| |
| testWithoutContext('--analyze-size is not supported in combination with --split-debug-info', () async { |
| final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); |
| final ProcessResult result = await processManager.run(<String>[ |
| flutterBin, |
| 'build', |
| 'apk', |
| '--analyze-size', |
| '--target-platform=android-arm64', |
| '--split-debug-info=infos', |
| ], workingDirectory: fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world')); |
| |
| expect(result.stderr.toString(), contains('"--analyze-size" cannot be combined with "--split-debug-info"')); |
| |
| expect(result.exitCode, 1); |
| }); |
| |
| testWithoutContext('--analyze-size allows overriding the directory for code size files', () async { |
| final String flutterBin = fileSystem.path.join(getFlutterRoot(), 'bin', 'flutter'); |
| final Directory tempDir = fileSystem.systemTempDirectory.createTempSync('flutter_size_test.'); |
| |
| final ProcessResult result = await processManager.run(<String>[ |
| flutterBin, |
| 'build', |
| 'apk', |
| '--analyze-size', |
| '--code-size-directory=${tempDir.path}', |
| '--target-platform=android-arm64', |
| '--release', |
| ], workingDirectory: fileSystem.path.join(getFlutterRoot(), 'examples', 'hello_world')); |
| |
| expect(result.exitCode, 0); |
| expect(tempDir.existsSync(), true); |
| expect(tempDir.childFile('snapshot.arm64-v8a.json').existsSync(), true); |
| expect(tempDir.childFile('trace.arm64-v8a.json').existsSync(), true); |
| |
| tempDir.deleteSync(recursive: true); |
| }); |
| } |