2019-11-27 23:04:02 +00:00
// Copyright 2014 The Flutter Authors. All rights reserved.
2019-04-17 19:16:55 +00:00
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
2021-01-27 23:17:53 +00:00
// @dart = 2.8
2019-07-22 22:34:03 +00:00
import ' package:args/command_runner.dart ' ;
2019-04-17 19:16:55 +00:00
import ' package:file/memory.dart ' ;
2020-02-20 02:46:04 +00:00
import ' package:file_testing/file_testing.dart ' ;
2019-04-17 19:16:55 +00:00
import ' package:flutter_tools/src/base/file_system.dart ' ;
2021-02-12 22:25:30 +00:00
import ' package:flutter_tools/src/base/os.dart ' ;
2020-05-06 15:15:39 +00:00
import ' package:flutter_tools/src/base/platform.dart ' ;
2020-05-16 22:07:34 +00:00
import ' package:flutter_tools/src/base/utils.dart ' ;
2021-02-12 22:25:30 +00:00
import ' package:flutter_tools/src/build_info.dart ' ;
2019-04-17 19:16:55 +00:00
import ' package:flutter_tools/src/cache.dart ' ;
2020-07-06 19:59:16 +00:00
import ' package:flutter_tools/src/cmake.dart ' ;
2019-04-17 19:16:55 +00:00
import ' package:flutter_tools/src/commands/build.dart ' ;
2019-09-02 06:57:11 +00:00
import ' package:flutter_tools/src/commands/build_linux.dart ' ;
2019-07-22 22:34:03 +00:00
import ' package:flutter_tools/src/features.dart ' ;
2019-04-24 20:34:56 +00:00
import ' package:flutter_tools/src/project.dart ' ;
2020-08-27 16:45:10 +00:00
import ' package:flutter_tools/src/reporting/reporting.dart ' ;
2021-02-08 17:21:46 +00:00
import ' package:process/process.dart ' ;
2021-02-18 08:46:02 +00:00
import ' package:test/fake.dart ' ;
2019-04-17 19:16:55 +00:00
2019-07-13 18:51:44 +00:00
import ' ../../src/common.dart ' ;
import ' ../../src/context.dart ' ;
2021-02-26 19:13:32 +00:00
import ' ../../src/fakes.dart ' ;
2019-07-22 22:34:03 +00:00
import ' ../../src/testbed.dart ' ;
2019-04-17 19:16:55 +00:00
2020-03-03 21:42:52 +00:00
const String _kTestFlutterRoot = ' /flutter ' ;
2020-02-20 02:46:04 +00:00
final Platform linuxPlatform = FakePlatform (
operatingSystem: ' linux ' ,
environment: < String , String > {
2020-12-03 01:19:57 +00:00
' FLUTTER_ROOT ' : _kTestFlutterRoot ,
' HOME ' : ' / ' ,
2020-02-20 02:46:04 +00:00
}
) ;
final Platform notLinuxPlatform = FakePlatform (
operatingSystem: ' macos ' ,
environment: < String , String > {
2020-03-03 21:42:52 +00:00
' FLUTTER_ROOT ' : _kTestFlutterRoot ,
2020-02-20 02:46:04 +00:00
}
) ;
void main ( ) {
2019-06-10 22:37:23 +00:00
setUpAll ( ( ) {
Cache . disableLocking ( ) ;
2019-04-17 19:16:55 +00:00
} ) ;
2019-06-10 22:37:23 +00:00
2020-02-20 02:46:04 +00:00
FileSystem fileSystem ;
ProcessManager processManager ;
2021-01-28 20:41:14 +00:00
TestUsage usage ;
2020-02-20 02:46:04 +00:00
2019-06-10 22:37:23 +00:00
setUp ( ( ) {
2020-02-20 02:46:04 +00:00
fileSystem = MemoryFileSystem . test ( ) ;
2020-03-03 21:42:52 +00:00
Cache . flutterRoot = _kTestFlutterRoot ;
2021-01-28 20:41:14 +00:00
usage = TestUsage ( ) ;
2019-04-17 19:16:55 +00:00
} ) ;
2020-01-08 20:39:49 +00:00
// Creates the mock files necessary to look like a Flutter project.
void setUpMockCoreProjectFiles ( ) {
2020-02-20 02:46:04 +00:00
fileSystem . file ( ' pubspec.yaml ' ) . createSync ( ) ;
fileSystem . file ( ' .packages ' ) . createSync ( ) ;
fileSystem . file ( fileSystem . path . join ( ' lib ' , ' main.dart ' ) ) . createSync ( recursive: true ) ;
2019-09-30 16:36:40 +00:00
}
2020-01-08 20:39:49 +00:00
// Creates the mock files necessary to run a build.
2020-06-24 19:23:57 +00:00
void setUpMockProjectFilesForBuild ( ) {
2020-01-08 20:39:49 +00:00
setUpMockCoreProjectFiles ( ) ;
2020-05-16 22:07:34 +00:00
fileSystem . file ( fileSystem . path . join ( ' linux ' , ' CMakeLists.txt ' ) ) . createSync ( recursive: true ) ;
2020-01-08 20:39:49 +00:00
}
2020-05-18 16:25:28 +00:00
// Returns the command matching the build_linux call to cmake.
2021-02-12 22:25:30 +00:00
FakeCommand cmakeCommand ( String buildMode , {
String target = ' x64 ' ,
void Function ( ) onRun ,
} ) {
2020-05-18 16:25:28 +00:00
return FakeCommand (
command: < String > [
' cmake ' ,
' -G ' ,
' Ninja ' ,
' -DCMAKE_BUILD_TYPE= ${ toTitleCase ( buildMode ) } ' ,
2021-02-12 22:25:30 +00:00
' -DFLUTTER_TARGET_PLATFORM=linux- $ target ' ,
2020-05-18 16:25:28 +00:00
' /linux ' ,
] ,
2021-02-12 22:25:30 +00:00
workingDirectory: ' build/linux/ $ target / $ buildMode ' ,
2020-05-18 16:25:28 +00:00
onRun: onRun ,
) ;
2020-05-16 22:07:34 +00:00
}
2020-05-18 16:25:28 +00:00
// Returns the command matching the build_linux call to ninja.
FakeCommand ninjaCommand ( String buildMode , {
Map < String , String > environment ,
2021-02-12 22:25:30 +00:00
String target = ' x64 ' ,
2020-05-18 16:25:28 +00:00
void Function ( ) onRun ,
String stdout = ' ' ,
} ) {
return FakeCommand (
command: < String > [
' ninja ' ,
' -C ' ,
2021-02-12 22:25:30 +00:00
' build/linux/ $ target / $ buildMode ' ,
2020-05-18 16:25:28 +00:00
' install ' ,
] ,
environment: environment ,
onRun: onRun ,
stdout: stdout ,
) ;
2020-05-16 22:07:34 +00:00
}
2019-04-17 19:16:55 +00:00
testUsingContext ( ' Linux build fails when there is no linux project ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
2020-01-08 20:39:49 +00:00
setUpMockCoreProjectFiles ( ) ;
2020-02-20 02:46:04 +00:00
2019-04-17 19:16:55 +00:00
expect ( createTestCommandRunner ( command ) . run (
2020-04-26 02:02:03 +00:00
const < String > [ ' build ' , ' linux ' , ' --no-pub ' ]
2021-02-16 17:51:03 +00:00
) , throwsToolExit ( message: ' No Linux desktop project configured. See '
' https://flutter.dev/desktop#add-desktop-support-to-an-existing-flutter-app '
' to learn about adding Linux support to a project. ' ) ) ;
2019-04-17 19:16:55 +00:00
} , overrides: < Type , Generator > {
Platform: ( ) = > linuxPlatform ,
2020-02-20 02:46:04 +00:00
FileSystem: ( ) = > fileSystem ,
2019-10-23 05:05:00 +00:00
ProcessManager: ( ) = > FakeProcessManager . any ( ) ,
2019-07-22 22:34:03 +00:00
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2019-04-17 19:16:55 +00:00
} ) ;
testUsingContext ( ' Linux build fails on non-linux platform ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
2019-09-30 16:36:40 +00:00
setUpMockProjectFilesForBuild ( ) ;
2019-04-17 19:16:55 +00:00
expect ( createTestCommandRunner ( command ) . run (
2020-04-26 02:02:03 +00:00
const < String > [ ' build ' , ' linux ' , ' --no-pub ' ]
2020-01-27 22:36:02 +00:00
) , throwsToolExit ( ) ) ;
2019-04-17 19:16:55 +00:00
} , overrides: < Type , Generator > {
Platform: ( ) = > notLinuxPlatform ,
2020-02-20 02:46:04 +00:00
FileSystem: ( ) = > fileSystem ,
2019-10-23 05:05:00 +00:00
ProcessManager: ( ) = > FakeProcessManager . any ( ) ,
2019-07-22 22:34:03 +00:00
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2019-04-17 19:16:55 +00:00
} ) ;
2020-05-16 22:07:34 +00:00
testUsingContext ( ' Linux build invokes CMake and ninja, and writes temporary files ' , ( ) async {
2019-04-17 19:16:55 +00:00
final BuildCommand command = BuildCommand ( ) ;
2020-02-20 02:46:04 +00:00
processManager = FakeProcessManager . list ( < FakeCommand > [
2020-05-18 16:25:28 +00:00
cmakeCommand ( ' release ' ) ,
ninjaCommand ( ' release ' ) ,
2020-02-20 02:46:04 +00:00
] ) ;
2019-09-30 16:36:40 +00:00
setUpMockProjectFilesForBuild ( ) ;
2019-04-17 19:16:55 +00:00
await createTestCommandRunner ( command ) . run (
2020-04-26 02:02:03 +00:00
const < String > [ ' build ' , ' linux ' , ' --no-pub ' ]
2019-04-17 19:16:55 +00:00
) ;
2020-05-16 22:07:34 +00:00
expect ( fileSystem . file ( ' linux/flutter/ephemeral/generated_config.cmake ' ) , exists ) ;
2019-04-17 19:16:55 +00:00
} , overrides: < Type , Generator > {
2020-02-20 02:46:04 +00:00
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
2019-04-17 19:16:55 +00:00
Platform: ( ) = > linuxPlatform ,
2019-07-22 22:34:03 +00:00
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
2019-04-17 19:16:55 +00:00
} ) ;
2019-04-24 20:34:56 +00:00
2020-05-16 22:07:34 +00:00
testUsingContext ( ' Handles argument error from missing cmake ' , ( ) async {
2019-10-08 21:53:55 +00:00
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
2020-02-20 02:46:04 +00:00
processManager = FakeProcessManager . list ( < FakeCommand > [
2020-05-18 16:25:28 +00:00
cmakeCommand ( ' release ' , onRun: ( ) {
2020-10-12 22:53:16 +00:00
throw ArgumentError ( ) ;
2020-02-20 02:46:04 +00:00
} ) ,
] ) ;
2019-10-08 21:53:55 +00:00
expect ( createTestCommandRunner ( command ) . run (
2020-04-26 02:02:03 +00:00
const < String > [ ' build ' , ' linux ' , ' --no-pub ' ]
2020-05-16 22:07:34 +00:00
) , throwsToolExit ( message: " cmake not found. Run 'flutter doctor' for more information. " ) ) ;
} , overrides: < Type , Generator > {
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
2020-05-16 22:07:34 +00:00
} ) ;
testUsingContext ( ' Handles argument error from missing ninja ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
processManager = FakeProcessManager . list ( < FakeCommand > [
2020-05-18 16:25:28 +00:00
cmakeCommand ( ' release ' ) ,
ninjaCommand ( ' release ' , onRun: ( ) {
2020-10-12 22:53:16 +00:00
throw ArgumentError ( ) ;
2020-05-16 22:07:34 +00:00
} ) ,
] ) ;
expect ( createTestCommandRunner ( command ) . run (
const < String > [ ' build ' , ' linux ' , ' --no-pub ' ]
) , throwsToolExit ( message: " ninja not found. Run 'flutter doctor' for more information. " ) ) ;
2019-10-08 21:53:55 +00:00
} , overrides: < Type , Generator > {
2020-02-20 02:46:04 +00:00
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
2019-10-08 21:53:55 +00:00
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
2019-10-08 21:53:55 +00:00
} ) ;
2019-10-28 17:27:11 +00:00
testUsingContext ( ' Linux build does not spew stdout to status logger ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
2020-02-20 02:46:04 +00:00
processManager = FakeProcessManager . list ( < FakeCommand > [
2020-05-18 16:25:28 +00:00
cmakeCommand ( ' debug ' ) ,
ninjaCommand ( ' debug ' ,
stdout: ' STDOUT STUFF ' ,
) ,
2020-02-20 02:46:04 +00:00
] ) ;
2019-10-28 17:27:11 +00:00
await createTestCommandRunner ( command ) . run (
2020-04-26 02:02:03 +00:00
const < String > [ ' build ' , ' linux ' , ' --debug ' , ' --no-pub ' ]
2019-10-28 17:27:11 +00:00
) ;
2019-11-24 05:54:43 +00:00
expect ( testLogger . statusText , isNot ( contains ( ' STDOUT STUFF ' ) ) ) ;
expect ( testLogger . traceText , contains ( ' STDOUT STUFF ' ) ) ;
2019-10-28 17:27:11 +00:00
} , overrides: < Type , Generator > {
2020-02-20 02:46:04 +00:00
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
2019-10-28 17:27:11 +00:00
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
2019-10-28 17:27:11 +00:00
} ) ;
2020-12-03 21:41:37 +00:00
testUsingContext ( ' Linux build extracts errors from stdout ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
// This contains a mix of routine build output and various types of errors
// (Dart error, compile error, link error), edited down for compactness.
const String stdout = r'' '
2021-02-12 22:25:30 +00:00
ninja: Entering directory ` build / linux / x64 / release '
2020-12-03 21:41:37 +00:00
[ 1 / 6 ] Generating / foo / linux / flutter / ephemeral / libflutter_linux_gtk . so , / foo / linux / flutter / ephemeral / flutter_linux / flutter_linux . h , _phony
lib / main . dart: 4 : 3 : Error: Method not found: ' foo ' .
[ 2 / 6 ] Building CXX object CMakeFiles / foo . dir / main . cc . o
/ foo / linux / main . cc: 6 : 2 : error: expected ' ; ' after class
/ foo / linux / main . cc: 9 : 7 : warning: unused variable ' unused_variable ' [ - Wunused - variable ]
/ foo / linux / main . cc: 10 : 3 : error: unknown type name ' UnknownType '
/ foo / linux / main . cc: 12 : 7 : error: ' bar ' is a private member of ' Foo '
2020-12-21 18:24:03 +00:00
/ foo / linux / my_application . h: 4 : 10 : fatal error: ' gtk/gtk.h ' file not found
2020-12-03 21:41:37 +00:00
[ 3 / 6 ] Building CXX object CMakeFiles / foo_bar . dir / flutter / generated_plugin_registrant . cc . o
[ 4 / 6 ] Building CXX object CMakeFiles / foo_bar . dir / my_application . cc . o
[ 5 / 6 ] Linking CXX executable intermediates_do_not_run / foo_bar
main . cc: ( . text + 0x13 ) : undefined reference to ` Foo: : bar ( ) '
clang: error: linker command failed with exit code 1 ( use - v to see invocation )
ninja: build stopped: subcommand failed .
2021-01-14 21:39:05 +00:00
ERROR: No file or variants found for asset: images / a_dot_burr . jpeg
2020-12-03 21:41:37 +00:00
''' ;
processManager = FakeProcessManager . list ( < FakeCommand > [
cmakeCommand ( ' release ' ) ,
ninjaCommand ( ' release ' ,
stdout: stdout ,
) ,
] ) ;
await createTestCommandRunner ( command ) . run (
const < String > [ ' build ' , ' linux ' , ' --no-pub ' ]
) ;
// Just the warnings and errors should be surfaced.
expect ( testLogger . errorText , r'' '
lib / main . dart: 4 : 3 : Error: Method not found: ' foo ' .
/ foo / linux / main . cc: 6 : 2 : error: expected ' ; ' after class
/ foo / linux / main . cc: 9 : 7 : warning: unused variable ' unused_variable ' [ - Wunused - variable ]
/ foo / linux / main . cc: 10 : 3 : error: unknown type name ' UnknownType '
/ foo / linux / main . cc: 12 : 7 : error: ' bar ' is a private member of ' Foo '
2020-12-21 18:24:03 +00:00
/ foo / linux / my_application . h: 4 : 10 : fatal error: ' gtk/gtk.h ' file not found
2020-12-03 21:41:37 +00:00
clang: error: linker command failed with exit code 1 ( use - v to see invocation )
2021-01-14 21:39:05 +00:00
ERROR: No file or variants found for asset: images / a_dot_burr . jpeg
2020-12-03 21:41:37 +00:00
''' );
} , overrides: < Type , Generator > {
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
2020-12-03 21:41:37 +00:00
} ) ;
2020-04-26 02:02:03 +00:00
testUsingContext ( ' Linux verbose build sets VERBOSE_SCRIPT_LOGGING ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
processManager = FakeProcessManager . list ( < FakeCommand > [
2020-05-18 16:25:28 +00:00
cmakeCommand ( ' debug ' ) ,
ninjaCommand ( ' debug ' ,
2020-05-16 22:07:34 +00:00
environment: const < String , String > {
2020-04-26 02:02:03 +00:00
' VERBOSE_SCRIPT_LOGGING ' : ' true '
} ,
stdout: ' STDOUT STUFF ' ,
) ,
] ) ;
await createTestCommandRunner ( command ) . run (
const < String > [ ' build ' , ' linux ' , ' --debug ' , ' -v ' , ' --no-pub ' ]
) ;
expect ( testLogger . statusText , contains ( ' STDOUT STUFF ' ) ) ;
expect ( testLogger . traceText , isNot ( contains ( ' STDOUT STUFF ' ) ) ) ;
} , overrides: < Type , Generator > {
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
2020-04-26 02:02:03 +00:00
} ) ;
2021-02-12 22:25:30 +00:00
testUsingContext ( ' Linux on x64 build --debug passes debug mode to cmake and ninja ' , ( ) async {
2019-09-30 16:36:40 +00:00
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
2020-02-20 02:46:04 +00:00
processManager = FakeProcessManager . list ( < FakeCommand > [
2020-05-18 16:25:28 +00:00
cmakeCommand ( ' debug ' ) ,
ninjaCommand ( ' debug ' ) ,
2020-02-20 02:46:04 +00:00
] ) ;
2021-02-12 22:25:30 +00:00
await createTestCommandRunner ( command ) . run (
const < String > [ ' build ' , ' linux ' , ' --debug ' , ' --no-pub ' ]
) ;
} , overrides: < Type , Generator > {
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
} ) ;
testUsingContext ( ' Linux on ARM64 build --debug passes debug mode to cmake and ninja ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
processManager = FakeProcessManager . list ( < FakeCommand > [
cmakeCommand ( ' debug ' , target: ' arm64 ' ) ,
ninjaCommand ( ' debug ' , target: ' arm64 ' ) ,
] ) ;
2019-09-30 16:36:40 +00:00
await createTestCommandRunner ( command ) . run (
2020-04-26 02:02:03 +00:00
const < String > [ ' build ' , ' linux ' , ' --debug ' , ' --no-pub ' ]
2019-09-30 16:36:40 +00:00
) ;
} , overrides: < Type , Generator > {
2020-02-20 02:46:04 +00:00
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
2019-09-30 16:36:40 +00:00
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > CustomFakeOperatingSystemUtils ( hostPlatform: HostPlatform . linux_arm64 ) ,
2019-09-30 16:36:40 +00:00
} ) ;
2021-02-12 22:25:30 +00:00
testUsingContext ( ' Linux on x64 build --profile passes profile mode to make ' , ( ) async {
2019-09-30 16:36:40 +00:00
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
2020-02-20 02:46:04 +00:00
processManager = FakeProcessManager . list ( < FakeCommand > [
2020-05-18 16:25:28 +00:00
cmakeCommand ( ' profile ' ) ,
ninjaCommand ( ' profile ' ) ,
2020-02-20 02:46:04 +00:00
] ) ;
2019-09-30 16:36:40 +00:00
await createTestCommandRunner ( command ) . run (
2020-04-26 02:02:03 +00:00
const < String > [ ' build ' , ' linux ' , ' --profile ' , ' --no-pub ' ]
2019-09-30 16:36:40 +00:00
) ;
} , overrides: < Type , Generator > {
2020-02-20 02:46:04 +00:00
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
2019-09-30 16:36:40 +00:00
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
} ) ;
testUsingContext ( ' Linux on ARM64 build --profile passes profile mode to make ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
processManager = FakeProcessManager . list ( < FakeCommand > [
cmakeCommand ( ' profile ' , target: ' arm64 ' ) ,
ninjaCommand ( ' profile ' , target: ' arm64 ' ) ,
] ) ;
await createTestCommandRunner ( command ) . run (
const < String > [ ' build ' , ' linux ' , ' --profile ' , ' --no-pub ' ]
) ;
} , overrides: < Type , Generator > {
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
OperatingSystemUtils: ( ) = > CustomFakeOperatingSystemUtils ( hostPlatform: HostPlatform . linux_arm64 ) ,
} ) ;
testUsingContext ( ' Not support Linux cross-build for x64 on arm64 ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
expect ( createTestCommandRunner ( command ) . run (
const < String > [ ' build ' , ' linux ' , ' --no-pub ' , ' --target-platform=linux-x64 ' ]
) , throwsToolExit ( ) ) ;
} , overrides: < Type , Generator > {
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
OperatingSystemUtils: ( ) = > CustomFakeOperatingSystemUtils ( hostPlatform: HostPlatform . linux_arm64 ) ,
2019-09-30 16:36:40 +00:00
} ) ;
2020-07-06 19:59:16 +00:00
testUsingContext ( ' Linux build configures CMake exports ' , ( ) async {
2020-04-26 02:02:03 +00:00
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
processManager = FakeProcessManager . list ( < FakeCommand > [
2020-05-18 16:25:28 +00:00
cmakeCommand ( ' release ' ) ,
ninjaCommand ( ' release ' ) ,
2020-04-26 02:02:03 +00:00
] ) ;
fileSystem . file ( ' lib/other.dart ' )
. createSync ( recursive: true ) ;
2020-10-12 19:49:51 +00:00
fileSystem . file ( ' foo/bar.sksl.json ' )
. createSync ( recursive: true ) ;
2020-04-26 02:02:03 +00:00
await createTestCommandRunner ( command ) . run (
const < String > [
' build ' ,
' linux ' ,
' --target=lib/other.dart ' ,
' --no-pub ' ,
' --track-widget-creation ' ,
' --split-debug-info=foo/ ' ,
' --enable-experiment=non-nullable ' ,
' --obfuscate ' ,
' --dart-define=foo.bar=2 ' ,
' --dart-define=fizz.far=3 ' ,
' --tree-shake-icons ' ,
2020-06-09 18:15:52 +00:00
' --bundle-sksl-path=foo/bar.sksl.json ' ,
2020-04-26 02:02:03 +00:00
]
) ;
2020-05-16 22:07:34 +00:00
final File cmakeConfig = fileSystem . currentDirectory
2020-04-26 02:02:03 +00:00
. childDirectory ( ' linux ' )
. childDirectory ( ' flutter ' )
. childDirectory ( ' ephemeral ' )
2020-05-16 22:07:34 +00:00
. childFile ( ' generated_config.cmake ' ) ;
2020-04-26 02:02:03 +00:00
2020-05-16 22:07:34 +00:00
expect ( cmakeConfig , exists ) ;
2020-04-26 02:02:03 +00:00
2020-05-16 22:07:34 +00:00
final List < String > configLines = cmakeConfig . readAsLinesSync ( ) ;
2020-04-26 02:02:03 +00:00
expect ( configLines , containsAll ( < String > [
2020-07-06 19:59:16 +00:00
' file(TO_CMAKE_PATH " $ _kTestFlutterRoot " FLUTTER_ROOT) ' ,
' file(TO_CMAKE_PATH " ${ fileSystem . currentDirectory . path } " PROJECT_DIR) ' ,
2021-02-02 17:10:48 +00:00
' "DART_DEFINES=Zm9vLmJhcj0y,Zml6ei5mYXI9Mw==" ' ,
2020-12-22 00:04:04 +00:00
' "DART_OBFUSCATION=true" ' ,
2021-02-02 17:10:48 +00:00
' "EXTRA_FRONT_END_OPTIONS=--enable-experiment=non-nullable" ' ,
' "EXTRA_GEN_SNAPSHOT_OPTIONS=--enable-experiment=non-nullable" ' ,
2020-12-22 00:04:04 +00:00
' "SPLIT_DEBUG_INFO=foo/" ' ,
' "TRACK_WIDGET_CREATION=true" ' ,
' "TREE_SHAKE_ICONS=true" ' ,
' "FLUTTER_ROOT= $ _kTestFlutterRoot " ' ,
' "PROJECT_DIR= ${ fileSystem . currentDirectory . path } " ' ,
' "FLUTTER_TARGET=lib/other.dart" ' ,
' "BUNDLE_SKSL_PATH=foo/bar.sksl.json" ' ,
2020-04-26 02:02:03 +00:00
] ) ) ;
} , overrides: < Type , Generator > {
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
2020-04-26 02:02:03 +00:00
} ) ;
2020-05-16 22:07:34 +00:00
testUsingContext ( ' linux can extract binary name from CMake file ' , ( ) async {
fileSystem . file ( ' linux/CMakeLists.txt ' )
2019-04-24 20:34:56 +00:00
. . createSync ( recursive: true )
. . writeAsStringSync ( r'' '
2020-05-16 22:07:34 +00:00
cmake_minimum_required ( VERSION 3.10 )
project ( runner LANGUAGES CXX )
2020-03-03 21:42:52 +00:00
2020-05-16 22:07:34 +00:00
set ( BINARY_NAME " fizz_bar " )
2019-04-24 20:34:56 +00:00
''' );
2020-02-20 02:46:04 +00:00
fileSystem . file ( ' pubspec.yaml ' ) . createSync ( ) ;
fileSystem . file ( ' .packages ' ) . createSync ( ) ;
2021-02-18 20:36:04 +00:00
final FlutterProject flutterProject = FlutterProject . fromDirectoryTest ( fileSystem . currentDirectory ) ;
2019-04-24 20:34:56 +00:00
2020-05-16 22:07:34 +00:00
expect ( getCmakeExecutableName ( flutterProject . linux ) , ' fizz_bar ' ) ;
2019-07-22 22:34:03 +00:00
} , overrides: < Type , Generator > {
2020-02-20 02:46:04 +00:00
FileSystem: ( ) = > fileSystem ,
2019-10-23 05:05:00 +00:00
ProcessManager: ( ) = > FakeProcessManager . any ( ) ,
2019-07-22 22:34:03 +00:00
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
} ) ;
testUsingContext ( ' Refuses to build for Linux when feature is disabled ' , ( ) {
final CommandRunner < void > runner = createTestCommandRunner ( BuildCommand ( ) ) ;
2020-04-26 02:02:03 +00:00
expect ( ( ) = > runner . run ( < String > [ ' build ' , ' linux ' , ' --no-pub ' ] ) ,
2020-02-20 02:46:04 +00:00
throwsToolExit ( ) ) ;
2019-07-22 22:34:03 +00:00
} , overrides: < Type , Generator > {
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: false ) ,
} ) ;
2019-08-21 03:16:29 +00:00
2019-09-02 06:57:11 +00:00
testUsingContext ( ' hidden when not enabled on Linux host ' , ( ) {
2021-02-12 22:25:30 +00:00
expect ( BuildLinuxCommand ( operatingSystemUtils: FakeOperatingSystemUtils ( ) ) . hidden , true ) ;
2019-09-02 06:57:11 +00:00
} , overrides: < Type , Generator > {
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: false ) ,
2020-02-20 02:46:04 +00:00
Platform: ( ) = > notLinuxPlatform ,
2019-09-02 06:57:11 +00:00
} ) ;
testUsingContext ( ' Not hidden when enabled and on Linux host ' , ( ) {
2021-02-12 22:25:30 +00:00
expect ( BuildLinuxCommand ( operatingSystemUtils: FakeOperatingSystemUtils ( ) ) . hidden , false ) ;
2019-09-02 06:57:11 +00:00
} , overrides: < Type , Generator > {
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
2020-02-20 02:46:04 +00:00
Platform: ( ) = > linuxPlatform ,
2019-09-02 06:57:11 +00:00
} ) ;
2020-08-27 16:45:10 +00:00
testUsingContext ( ' Performs code size analysis and sends analytics ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
processManager = FakeProcessManager . list ( < FakeCommand > [
cmakeCommand ( ' release ' ) ,
ninjaCommand ( ' release ' , onRun: ( ) {
fileSystem . file ( ' build/flutter_size_01/snapshot.linux-x64.json ' )
. . createSync ( recursive: true )
2020-10-15 22:37:04 +00:00
. . writeAsStringSync ( '''
[
{
" l " : " dart:_internal " ,
" c " : " SubListIterable " ,
" n " : " [Optimized] skip " ,
" s " : 2400
}
] ''' );
2020-08-27 16:45:10 +00:00
fileSystem . file ( ' build/flutter_size_01/trace.linux-x64.json ' )
. . createSync ( recursive: true )
. . writeAsStringSync ( ' {} ' ) ;
} ) ,
] ) ;
2021-02-12 22:25:30 +00:00
fileSystem . file ( ' build/linux/x64/release/bundle/libapp.so ' )
2020-08-27 16:45:10 +00:00
. . createSync ( recursive: true )
. . writeAsBytesSync ( List < int > . filled ( 10000 , 0 ) ) ;
2021-01-28 20:41:14 +00:00
await createTestCommandRunner ( command ) . run (
const < String > [ ' build ' , ' linux ' , ' --no-pub ' , ' --analyze-size ' ]
2020-08-27 16:45:10 +00:00
) ;
2020-10-08 23:09:49 +00:00
2020-08-27 16:45:10 +00:00
expect ( testLogger . statusText , contains ( ' A summary of your Linux bundle analysis can be found at ' ) ) ;
2020-12-15 19:06:10 +00:00
expect ( testLogger . statusText , contains ( ' flutter pub global activate devtools; flutter pub global run devtools --appSizeBase= ' ) ) ;
2021-01-28 20:41:14 +00:00
expect ( usage . events , contains (
const TestUsageEvent ( ' code-size-analysis ' , ' linux ' ) ,
) ) ;
2020-08-27 16:45:10 +00:00
} , overrides: < Type , Generator > {
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
Usage: ( ) = > usage ,
2021-02-12 22:25:30 +00:00
OperatingSystemUtils: ( ) = > FakeOperatingSystemUtils ( ) ,
2020-08-27 16:45:10 +00:00
} ) ;
2021-02-12 22:25:30 +00:00
testUsingContext ( ' Linux on ARM64 build --release passes, and check if the LinuxBuildDirectory for arm64 can be referenced correctly by using analytics ' , ( ) async {
final BuildCommand command = BuildCommand ( ) ;
setUpMockProjectFilesForBuild ( ) ;
processManager = FakeProcessManager . list ( < FakeCommand > [
cmakeCommand ( ' release ' , target: ' arm64 ' ) ,
ninjaCommand ( ' release ' , target: ' arm64 ' , onRun: ( ) {
fileSystem . file ( ' build/flutter_size_01/snapshot.linux-arm64.json ' )
. . createSync ( recursive: true )
. . writeAsStringSync ( '''
[
{
" l " : " dart:_internal " ,
" c " : " SubListIterable " ,
" n " : " [Optimized] skip " ,
" s " : 2400
}
] ''' );
fileSystem . file ( ' build/flutter_size_01/trace.linux-arm64.json ' )
. . createSync ( recursive: true )
. . writeAsStringSync ( ' {} ' ) ;
} ) ,
] ) ;
fileSystem . file ( ' build/linux/arm64/release/bundle/libapp.so ' )
. . createSync ( recursive: true )
. . writeAsBytesSync ( List < int > . filled ( 10000 , 0 ) ) ;
await createTestCommandRunner ( command ) . run (
const < String > [ ' build ' , ' linux ' , ' --no-pub ' , ' --analyze-size ' ]
) ;
// check if libapp.so of "build/linux/arm64/release" directory can be referenced.
expect ( testLogger . statusText , contains ( ' libapp.so (Dart AOT) ' ) ) ;
expect ( usage . events , contains (
const TestUsageEvent ( ' code-size-analysis ' , ' linux ' ) ,
) ) ;
} , overrides: < Type , Generator > {
FileSystem: ( ) = > fileSystem ,
ProcessManager: ( ) = > processManager ,
Platform: ( ) = > linuxPlatform ,
FeatureFlags: ( ) = > TestFeatureFlags ( isLinuxEnabled: true ) ,
Usage: ( ) = > usage ,
OperatingSystemUtils: ( ) = > CustomFakeOperatingSystemUtils ( hostPlatform: HostPlatform . linux_arm64 ) ,
} ) ;
}
class CustomFakeOperatingSystemUtils extends Fake implements OperatingSystemUtils {
CustomFakeOperatingSystemUtils ( {
HostPlatform hostPlatform = HostPlatform . linux_x64
} ) : _hostPlatform = hostPlatform ;
final HostPlatform _hostPlatform ;
@ override
String get name = > ' Linux ' ;
@ override
HostPlatform get hostPlatform = > _hostPlatform ;
@ override
List < File > whichAll ( String execName ) = > < File > [ ] ;
2020-08-27 16:45:10 +00:00
}