[flutter_tools] precache and unpack updates for desktop release artifacts (#55510)

- Update windows precache to include placeholder profile/release artifacts
- Update Linux and windows unpack to account for the cpp_client_wrapper code to live separate from the engine binaries
- Cleanup testing in unpack_linux and remove test cases that are covered in build_system_test.dart
This commit is contained in:
Jonah Williams 2020-04-25 14:27:55 -07:00 committed by GitHub
parent 0c4a659d18
commit d72eea539e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 290 additions and 174 deletions

View file

@ -49,8 +49,12 @@ enum Artifact {
iproxy,
/// The root of the Linux desktop sources.
linuxDesktopPath,
// The root of the cpp client code for Linux desktop.
linuxCppClientWrapper,
/// The root of the Windows desktop sources.
windowsDesktopPath,
/// The root of the cpp client code for Windows desktop.
windowsCppClientWrapper,
/// The root of the sky_engine package
skyEnginePath,
/// The location of the macOS engine podspec file.
@ -116,6 +120,10 @@ String _artifactToFileName(Artifact artifact, [ TargetPlatform platform, BuildMo
return '';
case Artifact.windowsDesktopPath:
return '';
case Artifact.windowsCppClientWrapper:
return 'cpp_client_wrapper';
case Artifact.linuxCppClientWrapper:
return 'cpp_client_wrapper_glfw';
case Artifact.skyEnginePath:
return 'sky_engine';
case Artifact.flutterMacOSPodspec:
@ -357,6 +365,12 @@ class CachedArtifacts extends Artifacts {
}
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
return _fileSystem.path.join(engineArtifactsPath, platformDirName, _artifactToFileName(artifact, platform, mode));
case Artifact.windowsCppClientWrapper:
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
return _fileSystem.path.join(engineArtifactsPath, 'windows-x64', _artifactToFileName(artifact, platform, mode));
case Artifact.linuxCppClientWrapper:
final String engineArtifactsPath = _cache.getArtifactDirectory('engine').path;
return _fileSystem.path.join(engineArtifactsPath, 'linux-x64', _artifactToFileName(artifact, platform, mode));
case Artifact.skyEnginePath:
final Directory dartPackageDirectory = _cache.getCacheDir('pkg');
return _fileSystem.path.join(dartPackageDirectory.path, _artifactToFileName(artifact));
@ -517,8 +531,12 @@ class LocalEngineArtifacts extends Artifacts {
return _cache.getArtifactDirectory('usbmuxd').childFile(artifactFileName).path;
case Artifact.linuxDesktopPath:
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
case Artifact.linuxCppClientWrapper:
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
case Artifact.windowsDesktopPath:
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
case Artifact.windowsCppClientWrapper:
return _fileSystem.path.join(_hostEngineOutPath, artifactFileName);
case Artifact.skyEnginePath:
return _fileSystem.path.join(_hostEngineOutPath, 'gen', 'dart-pkg', artifactFileName);
case Artifact.flutterMacOSPodspec:

View file

@ -7,59 +7,67 @@ import 'package:meta/meta.dart';
import '../../base/file_system.dart';
import '../depfile.dart';
/// Unpack the artifact list [artifacts] from [artifactPath] into a directory
/// [outputDirectory], returning a [Depfile] including all copied files.
/// Unpack the engine artifact list [artifacts] from [engineSourcePath] and
/// [clientSourcePath] (if provided) into a directory [outputDirectory].
///
/// Returns a [Depfile] including all copied files.
///
/// Throws an [Exception] if [artifacts] includes missing files, directories,
/// or links.
Depfile unpackDesktopArtifacts({
@required FileSystem fileSystem,
@required List<String> artifacts,
@required Directory outputDirectory,
@required String artifactPath,
@required String engineSourcePath,
String clientSourcePath,
}) {
final List<File> inputs = <File>[];
final List<File> outputs = <File>[];
for (final String artifact in artifacts) {
final String entityPath = fileSystem.path.join(artifactPath, artifact);
final String entityPath = fileSystem.path.join(engineSourcePath, artifact);
final FileSystemEntityType entityType = fileSystem.typeSync(entityPath);
if (entityType == FileSystemEntityType.notFound
|| entityType == FileSystemEntityType.directory
|| entityType == FileSystemEntityType.link) {
throw Exception('Unsupported file type: $entityType');
}
// If this artifact is a file then copy the source over.
if (entityType == FileSystemEntityType.file) {
final String outputPath = fileSystem.path.join(
outputDirectory.path,
fileSystem.path.relative(entityPath, from: artifactPath),
);
final File destinationFile = fileSystem.file(outputPath);
if (!destinationFile.parent.existsSync()) {
destinationFile.parent.createSync(recursive: true);
}
final File inputFile = fileSystem.file(entityPath);
inputFile.copySync(destinationFile.path);
inputs.add(inputFile);
outputs.add(destinationFile);
continue;
assert(entityType == FileSystemEntityType.file);
final String outputPath = fileSystem.path.join(
outputDirectory.path,
fileSystem.path.relative(entityPath, from: engineSourcePath),
);
final File destinationFile = fileSystem.file(outputPath);
if (!destinationFile.parent.existsSync()) {
destinationFile.parent.createSync(recursive: true);
}
// If the artifact is a directory, recursively copy every file from it.
for (final File input in fileSystem.directory(entityPath)
.listSync(recursive: true)
.whereType<File>()) {
final String outputPath = fileSystem.path.join(
outputDirectory.path,
fileSystem.path.relative(input.path, from: artifactPath),
);
final File destinationFile = fileSystem.file(outputPath);
if (!destinationFile.parent.existsSync()) {
destinationFile.parent.createSync(recursive: true);
}
final File inputFile = fileSystem.file(input);
inputFile.copySync(destinationFile.path);
inputs.add(inputFile);
outputs.add(destinationFile);
final File inputFile = fileSystem.file(entityPath);
inputFile.copySync(destinationFile.path);
inputs.add(inputFile);
outputs.add(destinationFile);
}
if (clientSourcePath == null) {
return Depfile(inputs, outputs);
}
final Directory clientSourceDirectory = fileSystem.directory(clientSourcePath);
if (!clientSourceDirectory.existsSync()) {
throw Exception('Missing clientSourceDirectory: $clientSourcePath');
}
for (final File input in clientSourceDirectory
.listSync(recursive: true)
.whereType<File>()) {
final String outputPath = fileSystem.path.join(
outputDirectory.path,
fileSystem.path.relative(input.path, from: clientSourceDirectory.parent.path),
);
final File destinationFile = fileSystem.file(outputPath);
if (!destinationFile.parent.existsSync()) {
destinationFile.parent.createSync(recursive: true);
}
final File inputFile = fileSystem.file(input);
inputFile.copySync(destinationFile.path);
inputs.add(inputFile);
outputs.add(destinationFile);
}
return Depfile(inputs, outputs);
}

View file

@ -5,7 +5,6 @@
import '../../artifacts.dart';
import '../../base/file_system.dart';
import '../../build_info.dart';
import '../../globals.dart' as globals;
import '../build_system.dart';
import '../depfile.dart';
import '../exceptions.dart';
@ -22,17 +21,16 @@ const List<String> _kLinuxArtifacts = <String>[
'flutter_plugin_registrar.h',
'flutter_glfw.h',
'icudtl.dat',
'cpp_client_wrapper_glfw/',
];
const String _kLinuxDepfile = 'linux_engine_sources.d';
/// Copies the Linux desktop embedding files to the copy directory.
class UnpackLinuxDebug extends Target {
const UnpackLinuxDebug();
class UnpackLinux extends Target {
const UnpackLinux();
@override
String get name => 'unpack_linux_debug';
String get name => 'unpack_linux';
@override
List<Source> get inputs => const <Source>[
@ -50,7 +48,19 @@ class UnpackLinuxDebug extends Target {
@override
Future<void> build(Environment environment) async {
final String artifactPath = globals.artifacts.getArtifactPath(Artifact.linuxDesktopPath);
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
final String engineSourcePath = environment.artifacts
.getArtifactPath(
Artifact.linuxDesktopPath,
mode: buildMode,
platform: TargetPlatform.linux_x64,
);
final String clientSourcePath = environment.artifacts
.getArtifactPath(
Artifact.linuxCppClientWrapper,
mode: buildMode,
platform: TargetPlatform.linux_x64,
);
final Directory outputDirectory = environment.fileSystem.directory(
environment.fileSystem.path.join(
environment.projectDir.path,
@ -60,13 +70,14 @@ class UnpackLinuxDebug extends Target {
));
final Depfile depfile = unpackDesktopArtifacts(
fileSystem: environment.fileSystem,
artifactPath: artifactPath,
engineSourcePath: engineSourcePath,
outputDirectory: outputDirectory,
artifacts: _kLinuxArtifacts,
clientSourcePath: clientSourcePath,
);
final DepfileService depfileService = DepfileService(
fileSystem: globals.fs,
logger: globals.logger,
fileSystem: environment.fileSystem,
logger: environment.logger,
);
depfileService.writeToFile(
depfile,
@ -85,7 +96,7 @@ class DebugBundleLinuxAssets extends Target {
@override
List<Target> get dependencies => const <Target>[
KernelSnapshot(),
UnpackLinuxDebug(),
UnpackLinux(),
];
@override
@ -125,8 +136,8 @@ class DebugBundleLinuxAssets extends Target {
}
final Depfile depfile = await copyAssets(environment, outputDirectory);
final DepfileService depfileService = DepfileService(
fileSystem: globals.fs,
logger: globals.logger,
fileSystem: environment.fileSystem,
logger: environment.logger,
);
depfileService.writeToFile(
depfile,

View file

@ -24,7 +24,6 @@ const List<String> _kWindowsArtifacts = <String>[
'flutter_plugin_registrar.h',
'flutter_windows.h',
'icudtl.dat',
'cpp_client_wrapper',
];
const String _kWindowsDepfile = 'windows_engine_sources.d';
@ -52,7 +51,19 @@ class UnpackWindows extends Target {
@override
Future<void> build(Environment environment) async {
final String artifactPath = environment.artifacts.getArtifactPath(Artifact.windowsDesktopPath);
final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]);
final String engineSourcePath = environment.artifacts
.getArtifactPath(
Artifact.windowsDesktopPath,
platform: TargetPlatform.windows_x64,
mode: buildMode,
);
final String clientSourcePath = environment.artifacts
.getArtifactPath(
Artifact.windowsCppClientWrapper,
platform: TargetPlatform.windows_x64,
mode: buildMode,
);
final Directory outputDirectory = environment.fileSystem.directory(
environment.fileSystem.path.join(
environment.projectDir.path,
@ -64,8 +75,9 @@ class UnpackWindows extends Target {
final Depfile depfile = unpackDesktopArtifacts(
fileSystem: environment.fileSystem,
artifacts: _kWindowsArtifacts,
artifactPath: artifactPath,
engineSourcePath: engineSourcePath,
outputDirectory: outputDirectory,
clientSourcePath: clientSourcePath,
);
final DepfileService depfileService = DepfileService(
fileSystem: environment.fileSystem,

View file

@ -118,9 +118,9 @@ class Cache {
_artifacts.add(IOSEngineArtifacts(this));
_artifacts.add(FlutterWebSdk(this));
_artifacts.add(FlutterSdk(this));
_artifacts.add(WindowsEngineArtifacts(this));
_artifacts.add(WindowsEngineArtifacts(this, platform: _platform));
_artifacts.add(MacOSEngineArtifacts(this));
_artifacts.add(LinuxEngineArtifacts(this));
_artifacts.add(LinuxEngineArtifacts(this, platform: _platform));
_artifacts.add(LinuxFuchsiaSDKArtifacts(this));
_artifacts.add(MacOSFuchsiaSDKArtifacts(this));
_artifacts.add(FlutterRunnerSDKArtifacts(this));
@ -879,19 +879,25 @@ class MacOSEngineArtifacts extends EngineCachedArtifact {
List<String> getLicenseDirs() => const <String>[];
}
/// Artifacts required for desktop Windows builds.
class WindowsEngineArtifacts extends EngineCachedArtifact {
WindowsEngineArtifacts(Cache cache) : super(
'windows-sdk',
cache,
DevelopmentArtifact.windows,
);
WindowsEngineArtifacts(Cache cache, {
@required Platform platform,
}) : _platform = platform,
super(
'windows-sdk',
cache,
DevelopmentArtifact.windows,
);
final Platform _platform;
@override
List<String> getPackageDirs() => const <String>[];
@override
List<List<String>> getBinaryDirs() {
if (globals.platform.isWindows || ignorePlatformFiltering) {
if (_platform.isWindows || ignorePlatformFiltering) {
return _windowsDesktopBinaryDirs;
}
return const <List<String>>[];
@ -901,19 +907,25 @@ class WindowsEngineArtifacts extends EngineCachedArtifact {
List<String> getLicenseDirs() => const <String>[];
}
/// Artifacts required for desktop Linux builds.
class LinuxEngineArtifacts extends EngineCachedArtifact {
LinuxEngineArtifacts(Cache cache) : super(
'linux-sdk',
cache,
DevelopmentArtifact.linux,
);
LinuxEngineArtifacts(Cache cache, {
@required Platform platform
}) : _platform = platform,
super(
'linux-sdk',
cache,
DevelopmentArtifact.linux,
);
final Platform _platform;
@override
List<String> getPackageDirs() => const <String>[];
@override
List<List<String>> getBinaryDirs() {
if (globals.platform.isLinux || ignorePlatformFiltering) {
if (_platform.isLinux || ignorePlatformFiltering) {
return _linuxDesktopBinaryDirs;
}
return const <List<String>>[];
@ -1364,9 +1376,14 @@ void _ensureExists(Directory directory) {
}
}
// TODO(jonahwilliams): upload debug desktop artifacts to host-debug and
// remove from existing host folder.
// https://github.com/flutter/flutter/issues/38935
const List<List<String>> _windowsDesktopBinaryDirs = <List<String>>[
<String>['windows-x64', 'windows-x64/windows-x64-flutter.zip'],
<String>['windows-x64', 'windows-x64/flutter-cpp-client-wrapper.zip'],
<String>['windows-x64-profile', 'windows-x64-profile/windows-x64-flutter.zip'],
<String>['windows-x64-release', 'windows-x64-release/windows-x64-flutter.zip'],
];
const List<List<String>> _linuxDesktopBinaryDirs = <List<String>>[
@ -1374,9 +1391,6 @@ const List<List<String>> _linuxDesktopBinaryDirs = <List<String>>[
<String>['linux-x64', 'linux-x64/flutter-cpp-client-wrapper-glfw.zip'],
];
// TODO(jonahwilliams): upload debug desktop artifacts to host-debug and
// remove from existing host folder.
// https://github.com/flutter/flutter/issues/38935
const List<List<String>> _macOSDesktopBinaryDirs = <List<String>>[
<String>['darwin-x64', 'darwin-x64/FlutterMacOS.framework.zip'],
<String>['darwin-x64-profile', 'darwin-x64-profile/FlutterMacOS.framework.zip'],

View file

@ -17,19 +17,19 @@ void main() {
// Should be copied.
fileSystem.file('inputs/a.txt').createSync();
fileSystem.file('inputs/b.txt').createSync();
fileSystem.file('inputs/foo/c.txt').createSync();
fileSystem.file('foo/c.txt').createSync(recursive: true);
// Sould not be copied.
fileSystem.file('inputs/d.txt').createSync();
final Depfile depfile = unpackDesktopArtifacts(
fileSystem: fileSystem,
artifactPath: 'inputs',
engineSourcePath: 'inputs',
outputDirectory: fileSystem.directory('outputs'),
artifacts: <String>[
'a.txt',
'b.txt',
'foo/'
],
clientSourcePath: 'foo',
);
// Files are copied
@ -42,7 +42,7 @@ void main() {
expect(depfile.inputs.map((File file) => file.path), unorderedEquals(<String>[
'inputs/a.txt',
'inputs/b.txt',
'inputs/foo/c.txt',
'foo/c.txt',
]));
expect(depfile.outputs.map((File file) => file.path), unorderedEquals(<String>[
'outputs/a.txt',
@ -56,11 +56,41 @@ void main() {
expect(() => unpackDesktopArtifacts(
fileSystem: fileSystem,
artifactPath: 'inputs',
engineSourcePath: 'inputs',
outputDirectory: fileSystem.directory('outputs'),
artifacts: <String>[
'a.txt',
],
clientSourcePath: 'foo'
), throwsA(isA<Exception>()));
});
testWithoutContext('unpackDesktopArtifacts throws when attempting to copy missing directory', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
fileSystem.file('inputs/a.txt').createSync(recursive: true);
expect(() => unpackDesktopArtifacts(
fileSystem: fileSystem,
engineSourcePath: 'inputs',
outputDirectory: fileSystem.directory('outputs'),
artifacts: <String>[
'a.txt',
],
clientSourcePath: 'foo'
), throwsA(isA<Exception>()));
});
testWithoutContext('unpackDesktopArtifacts does not require a client source path', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
fileSystem.file('inputs/a.txt').createSync(recursive: true);
expect(() => unpackDesktopArtifacts(
fileSystem: fileSystem,
engineSourcePath: 'inputs',
outputDirectory: fileSystem.directory('outputs'),
artifacts: <String>[
'a.txt',
],
), returnsNormally);
});
}

View file

@ -2,118 +2,106 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:file/memory.dart';
import 'package:file_testing/file_testing.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:platform/platform.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/build_system/targets/dart.dart';
import 'package:flutter_tools/src/build_system/targets/linux.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:mockito/mockito.dart';
import '../../../src/common.dart';
import '../../../src/context.dart';
import '../../../src/testbed.dart';
void main() {
Testbed testbed;
BuildSystem buildSystem;
Environment environment;
MockPlatform mockPlatform;
testWithoutContext('Copies files to correct cache directory, excluding unrelated code', () async {
final FileSystem fileSystem = MemoryFileSystem.test();
setUpCacheDirectory(fileSystem);
final MockArtifacts mockArtifacts = MockArtifacts();
when(mockArtifacts.getArtifactPath(
Artifact.linuxDesktopPath,
mode: anyNamed('mode'),
platform: anyNamed('platform'),
)).thenReturn('linux-x64');
when(mockArtifacts.getArtifactPath(
Artifact.linuxCppClientWrapper,
mode: anyNamed('mode'),
platform: anyNamed('platform'),
)).thenReturn('linux-x64/cpp_client_wrapper_glfw');
setUpAll(() {
Cache.disableLocking();
Cache.flutterRoot = '';
final Environment testEnvironment = Environment.test(
fileSystem.currentDirectory,
defines: <String, String>{
kBuildMode: 'debug',
},
artifacts: mockArtifacts,
processManager: FakeProcessManager.any(),
fileSystem: fileSystem,
logger: BufferLogger.test(),
);
testEnvironment.buildDir.createSync(recursive: true);
await const UnpackLinux().build(testEnvironment);
expect(fileSystem.file('linux/flutter/ephemeral/libflutter_linux_glfw.so'), exists);
expect(fileSystem.file('linux/flutter/ephemeral/flutter_export.h'), exists);
expect(fileSystem.file('linux/flutter/ephemeral/flutter_messenger.h'), exists);
expect(fileSystem.file('linux/flutter/ephemeral/flutter_plugin_registrar.h'), exists);
expect(fileSystem.file('linux/flutter/ephemeral/flutter_glfw.h'), exists);
expect(fileSystem.file('linux/flutter/ephemeral/icudtl.dat'), exists);
expect(fileSystem.file('linux/flutter/ephemeral/cpp_client_wrapper_glfw/foo'), exists);
expect(fileSystem.file('linux/flutter/ephemeral/unrelated-stuff'), isNot(exists));
});
// Only required for the test below that still depends on the context.
FileSystem fileSystem;
setUp(() {
mockPlatform = MockPlatform();
when(mockPlatform.isWindows).thenReturn(false);
when(mockPlatform.isMacOS).thenReturn(false);
when(mockPlatform.isLinux).thenReturn(true);
when(mockPlatform.environment).thenReturn(Map<String, String>.unmodifiable(<String, String>{}));
testbed = Testbed(setup: () {
Cache.flutterRoot = '';
buildSystem = BuildSystem(
logger: globals.logger,
platform: globals.platform,
fileSystem: globals.fs,
);
environment = Environment.test(
globals.fs.currentDirectory,
defines: <String, String>{
kBuildMode: 'debug',
},
artifacts: MockArtifacts(),
processManager: FakeProcessManager.any(),
fileSystem: globals.fs,
logger: globals.logger,
);
globals.fs.file('bin/cache/artifacts/engine/linux-x64/unrelated-stuff').createSync(recursive: true);
globals.fs.file('bin/cache/artifacts/engine/linux-x64/libflutter_linux_glfw.so').createSync(recursive: true);
globals.fs.file('bin/cache/artifacts/engine/linux-x64/flutter_export.h').createSync();
globals.fs.file('bin/cache/artifacts/engine/linux-x64/flutter_messenger.h').createSync();
globals.fs.file('bin/cache/artifacts/engine/linux-x64/flutter_plugin_registrar.h').createSync();
globals.fs.file('bin/cache/artifacts/engine/linux-x64/flutter_glfw.h').createSync();
globals.fs.file('bin/cache/artifacts/engine/linux-x64/icudtl.dat').createSync();
globals.fs.file('bin/cache/artifacts/engine/linux-x64/cpp_client_wrapper_glfw/foo').createSync(recursive: true);
globals.fs.file('packages/flutter_tools/lib/src/build_system/targets/linux.dart').createSync(recursive: true);
globals.fs.directory('linux').createSync();
}, overrides: <Type, Generator>{
Platform: () => mockPlatform,
});
fileSystem = MemoryFileSystem.test();
});
test('Copies files to correct cache directory, excluding unrelated code', () => testbed.run(() async {
final BuildResult result = await buildSystem.build(const UnpackLinuxDebug(), environment);
testUsingContext('DebugBundleLinuxAssets copies artifacts to out directory', () async {
final Environment testEnvironment = Environment.test(
fileSystem.currentDirectory,
defines: <String, String>{
kBuildMode: 'debug',
},
artifacts: MockArtifacts(),
processManager: FakeProcessManager.any(),
fileSystem: fileSystem,
logger: BufferLogger.test(),
);
expect(result.hasException, false);
expect(globals.fs.file('linux/flutter/ephemeral/libflutter_linux_glfw.so').existsSync(), true);
expect(globals.fs.file('linux/flutter/ephemeral/flutter_export.h').existsSync(), true);
expect(globals.fs.file('linux/flutter/ephemeral/flutter_messenger.h').existsSync(), true);
expect(globals.fs.file('linux/flutter/ephemeral/flutter_plugin_registrar.h').existsSync(), true);
expect(globals.fs.file('linux/flutter/ephemeral/flutter_glfw.h').existsSync(), true);
expect(globals.fs.file('linux/flutter/ephemeral/icudtl.dat').existsSync(), true);
expect(globals.fs.file('linux/flutter/ephemeral/cpp_client_wrapper_glfw/foo').existsSync(), true);
expect(globals.fs.file('linux/flutter/ephemeral/unrelated-stuff').existsSync(), false);
}));
test('Does not re-copy files unecessarily', () => testbed.run(() async {
await buildSystem.build(const UnpackLinuxDebug(), environment);
// Set a date in the far distant past to deal with the limited resolution
// of the windows filesystem.
final DateTime theDistantPast = DateTime(1991, 8, 23);
globals.fs.file('linux/flutter/ephemeral/libflutter_linux_glfw.so').setLastModifiedSync(theDistantPast);
await buildSystem.build(const UnpackLinuxDebug(), environment);
expect(globals.fs.file('linux/flutter/ephemeral/libflutter_linux_glfw.so').statSync().modified, equals(theDistantPast));
}));
test('Detects changes in input cache files', () => testbed.run(() async {
await buildSystem.build(const UnpackLinuxDebug(), environment);
globals.fs.file('bin/cache/artifacts/engine/linux-x64/libflutter_linux_glfw.so').writeAsStringSync('asd'); // modify cache.
await buildSystem.build(const UnpackLinuxDebug(), environment);
expect(globals.fs.file('linux/flutter/ephemeral/libflutter_linux_glfw.so').readAsStringSync(), 'asd');
}));
test('Copies artifacts to out directory', () => testbed.run(() async {
environment.buildDir.createSync(recursive: true);
testEnvironment.buildDir.createSync(recursive: true);
// Create input files.
environment.buildDir.childFile('app.dill').createSync();
testEnvironment.buildDir.childFile('app.dill').createSync();
await const DebugBundleLinuxAssets().build(environment);
final Directory output = environment.outputDir
await const DebugBundleLinuxAssets().build(testEnvironment);
final Directory output = testEnvironment.outputDir
.childDirectory('flutter_assets');
expect(output.childFile('kernel_blob.bin').existsSync(), true);
expect(output.childFile('FontManifest.json').existsSync(), false);
expect(output.childFile('AssetManifest.json').existsSync(), true);
}));
expect(output.childFile('kernel_blob.bin'), exists);
expect(output.childFile('AssetManifest.json'), exists);
// No bundled fonts
expect(output.childFile('FontManifest.json'), isNot(exists));
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
}
void setUpCacheDirectory(FileSystem fileSystem) {
fileSystem.file('linux-x64/unrelated-stuff').createSync(recursive: true);
fileSystem.file('linux-x64/libflutter_linux_glfw.so').createSync(recursive: true);
fileSystem.file('linux-x64/flutter_export.h').createSync();
fileSystem.file('linux-x64/flutter_messenger.h').createSync();
fileSystem.file('linux-x64/flutter_plugin_registrar.h').createSync();
fileSystem.file('linux-x64/flutter_glfw.h').createSync();
fileSystem.file('linux-x64/icudtl.dat').createSync();
fileSystem.file('linux-x64/cpp_client_wrapper_glfw/foo').createSync(recursive: true);
fileSystem.file('packages/flutter_tools/lib/src/build_system/targets/linux.dart').createSync(recursive: true);
}
class MockPlatform extends Mock implements Platform {}
class MockArtifacts extends Mock implements Artifacts {}

View file

@ -47,6 +47,9 @@ void main() {
processManager: FakeProcessManager.any(),
fileSystem: fileSystem,
logger: BufferLogger.test(),
defines: <String, String>{
kBuildMode: 'debug',
}
);
final DepfileService depfileService = DepfileService(
logger: BufferLogger.test(),
@ -54,8 +57,16 @@ void main() {
);
environment.buildDir.createSync(recursive: true);
when(artifacts.getArtifactPath(Artifact.windowsDesktopPath))
.thenReturn(r'C:\bin\cache\artifacts\engine\windows-x64\');
when(artifacts.getArtifactPath(
Artifact.windowsDesktopPath,
mode: anyNamed('mode'),
platform: anyNamed('platform')
)).thenReturn(r'C:\bin\cache\artifacts\engine\windows-x64\');
when(artifacts.getArtifactPath(
Artifact.windowsCppClientWrapper,
mode: anyNamed('mode'),
platform: anyNamed('platform')
)).thenReturn(r'C:\bin\cache\artifacts\engine\windows-x64\cpp_client_wrapper\');
for (final String path in kRequiredFiles) {
fileSystem.file(path).createSync(recursive: true);
}
@ -117,8 +128,13 @@ void main() {
});
// AssetBundleFactory still uses context injection
FileSystem fileSystem;
setUp(() {
fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
});
testUsingContext('DebugBundleWindowsAssets creates correct bundle structure', () async {
final FileSystem fileSystem = MemoryFileSystem.test(style: FileSystemStyle.windows);
final Environment environment = Environment.test(
fileSystem.currentDirectory,
artifacts: MockArtifacts(),
@ -137,6 +153,10 @@ void main() {
// Depfile is created and dill is copied.
expect(environment.buildDir.childFile('flutter_assets.d'), exists);
expect(fileSystem.file(r'C:\flutter_assets\kernel_blob.bin'), exists);
expect(fileSystem.file(r'C:\flutter_assets\AssetManifest.json'), exists);
}, overrides: <Type, Generator>{
FileSystem: () => fileSystem,
ProcessManager: () => FakeProcessManager.any(),
});
}

View file

@ -574,26 +574,41 @@ void main() {
Platform: () => FakePlatform(operatingSystem: 'linux'),
});
testUsingContext('Windows desktop artifacts ignore filtering when requested', () {
testWithoutContext('Windows desktop artifacts ignore filtering when requested', () {
final MockCache mockCache = MockCache();
final WindowsEngineArtifacts artifacts = WindowsEngineArtifacts(mockCache);
final WindowsEngineArtifacts artifacts = WindowsEngineArtifacts(
mockCache,
platform: FakePlatform(operatingSystem: 'linux'),
);
when(mockCache.includeAllPlatforms).thenReturn(false);
when(mockCache.platformOverrideArtifacts).thenReturn(<String>{'windows'});
expect(artifacts.getBinaryDirs(), isNotEmpty);
}, overrides: <Type, Generator> {
Platform: () => FakePlatform(operatingSystem: 'linux'),
});
testUsingContext('Linux desktop artifacts ignore filtering when requested', () {
testWithoutContext('Windows desktop artifacts include profile and release artifacts', () {
final MockCache mockCache = MockCache();
final LinuxEngineArtifacts artifacts = LinuxEngineArtifacts(mockCache);
final WindowsEngineArtifacts artifacts = WindowsEngineArtifacts(
mockCache,
platform: FakePlatform(operatingSystem: 'windows'),
);
expect(artifacts.getBinaryDirs(), containsAll(<Matcher>[
contains(contains('profile')),
contains(contains('release')),
]));
});
testWithoutContext('Linux desktop artifacts ignore filtering when requested', () {
final MockCache mockCache = MockCache();
final LinuxEngineArtifacts artifacts = LinuxEngineArtifacts(
mockCache,
platform: FakePlatform(operatingSystem: 'macos'),
);
when(mockCache.includeAllPlatforms).thenReturn(false);
when(mockCache.platformOverrideArtifacts).thenReturn(<String>{'linux'});
expect(artifacts.getBinaryDirs(), isNotEmpty);
}, overrides: <Type, Generator> {
Platform: () => FakePlatform(operatingSystem: 'macos'),
});
}