Unverified Commit 219dd6ca authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Migrate assemble and integration_test_device to null safety (#96630)

parent dafda50c
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8 import 'package:args/args.dart';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
import '../artifacts.dart';
import '../base/common.dart'; import '../base/common.dart';
import '../base/file_system.dart'; import '../base/file_system.dart';
import '../build_info.dart'; import '../build_info.dart';
...@@ -88,7 +88,7 @@ List<Target> _kDefaultTargets = <Target>[ ...@@ -88,7 +88,7 @@ List<Target> _kDefaultTargets = <Target>[
/// Assemble provides a low level API to interact with the flutter tool build /// Assemble provides a low level API to interact with the flutter tool build
/// system. /// system.
class AssembleCommand extends FlutterCommand { class AssembleCommand extends FlutterCommand {
AssembleCommand({ bool verboseHelp = false, @required BuildSystem buildSystem }) AssembleCommand({ bool verboseHelp = false, required BuildSystem buildSystem })
: _buildSystem = buildSystem { : _buildSystem = buildSystem {
argParser.addMultiOption( argParser.addMultiOption(
'define', 'define',
...@@ -161,13 +161,13 @@ class AssembleCommand extends FlutterCommand { ...@@ -161,13 +161,13 @@ class AssembleCommand extends FlutterCommand {
@override @override
Future<Set<DevelopmentArtifact>> get requiredArtifacts async { Future<Set<DevelopmentArtifact>> get requiredArtifacts async {
final String platform = environment.defines[kTargetPlatform]; final String? platform = environment.defines[kTargetPlatform];
if (platform == null) { if (platform == null) {
return super.requiredArtifacts; return super.requiredArtifacts;
} }
final TargetPlatform targetPlatform = getTargetPlatformForName(platform); final TargetPlatform targetPlatform = getTargetPlatformForName(platform);
final DevelopmentArtifact artifact = artifactFromTargetPlatform(targetPlatform); final DevelopmentArtifact? artifact = artifactFromTargetPlatform(targetPlatform);
if (artifact != null) { if (artifact != null) {
return <DevelopmentArtifact>{artifact}; return <DevelopmentArtifact>{artifact};
} }
...@@ -176,18 +176,19 @@ class AssembleCommand extends FlutterCommand { ...@@ -176,18 +176,19 @@ class AssembleCommand extends FlutterCommand {
/// The target(s) we are building. /// The target(s) we are building.
List<Target> createTargets() { List<Target> createTargets() {
if (argResults.rest.isEmpty) { final ArgResults argumentResults = argResults!;
if (argumentResults.rest.isEmpty) {
throwToolExit('missing target name for flutter assemble.'); throwToolExit('missing target name for flutter assemble.');
} }
final String name = argResults.rest.first; final String name = argumentResults.rest.first;
final Map<String, Target> targetMap = <String, Target>{ final Map<String, Target> targetMap = <String, Target>{
for (final Target target in _kDefaultTargets) for (final Target target in _kDefaultTargets)
target.name: target target.name: target
}; };
final List<Target> results = <Target>[ final List<Target> results = <Target>[
for (final String targetName in argResults.rest) for (final String targetName in argumentResults.rest)
if (targetMap.containsKey(targetName)) if (targetMap.containsKey(targetName))
targetMap[targetName] targetMap[targetName]!
]; ];
if (results.isEmpty) { if (results.isEmpty) {
throwToolExit('No target named "$name" defined.'); throwToolExit('No target named "$name" defined.');
...@@ -196,7 +197,7 @@ class AssembleCommand extends FlutterCommand { ...@@ -196,7 +197,7 @@ class AssembleCommand extends FlutterCommand {
} }
bool isDeferredComponentsTargets() { bool isDeferredComponentsTargets() {
for (final String targetName in argResults.rest) { for (final String targetName in argResults!.rest) {
if (deferredComponentsTargets.contains(targetName)) { if (deferredComponentsTargets.contains(targetName)) {
return true; return true;
} }
...@@ -205,7 +206,7 @@ class AssembleCommand extends FlutterCommand { ...@@ -205,7 +206,7 @@ class AssembleCommand extends FlutterCommand {
} }
bool isDebug() { bool isDebug() {
for (final String targetName in argResults.rest) { for (final String targetName in argResults!.rest) {
if (targetName.contains('debug')) { if (targetName.contains('debug')) {
return true; return true;
} }
...@@ -213,13 +214,12 @@ class AssembleCommand extends FlutterCommand { ...@@ -213,13 +214,12 @@ class AssembleCommand extends FlutterCommand {
return false; return false;
} }
Environment get environment => _environment ??= createEnvironment(); late final Environment environment = createEnvironment();
Environment _environment;
/// The environmental configuration for a build invocation. /// The environmental configuration for a build invocation.
Environment createEnvironment() { Environment createEnvironment() {
final FlutterProject flutterProject = FlutterProject.current(); final FlutterProject flutterProject = FlutterProject.current();
String output = stringArg('output'); String? output = stringArg('output');
if (output == null) { if (output == null) {
throwToolExit('--output directory is required for assemble.'); throwToolExit('--output directory is required for assemble.');
} }
...@@ -227,6 +227,7 @@ class AssembleCommand extends FlutterCommand { ...@@ -227,6 +227,7 @@ class AssembleCommand extends FlutterCommand {
if (globals.fs.path.isRelative(output)) { if (globals.fs.path.isRelative(output)) {
output = globals.fs.path.join(flutterProject.directory.path, output); output = globals.fs.path.join(flutterProject.directory.path, output);
} }
final Artifacts artifacts = globals.artifacts!;
final Environment result = Environment( final Environment result = Environment(
outputDir: globals.fs.directory(output), outputDir: globals.fs.directory(output),
buildDir: flutterProject.directory buildDir: flutterProject.directory
...@@ -237,12 +238,12 @@ class AssembleCommand extends FlutterCommand { ...@@ -237,12 +238,12 @@ class AssembleCommand extends FlutterCommand {
inputs: _parseDefines(stringsArg('input')), inputs: _parseDefines(stringsArg('input')),
cacheDir: globals.cache.getRoot(), cacheDir: globals.cache.getRoot(),
flutterRootDir: globals.fs.directory(Cache.flutterRoot), flutterRootDir: globals.fs.directory(Cache.flutterRoot),
artifacts: globals.artifacts, artifacts: artifacts,
fileSystem: globals.fs, fileSystem: globals.fs,
logger: globals.logger, logger: globals.logger,
processManager: globals.processManager, processManager: globals.processManager,
platform: globals.platform, platform: globals.platform,
engineVersion: globals.artifacts.isLocalEngine engineVersion: artifacts.isLocalEngine
? null ? null
: globals.flutterVersion.engineRevision, : globals.flutterVersion.engineRevision,
generateDartPluginRegistry: true, generateDartPluginRegistry: true,
...@@ -261,18 +262,19 @@ class AssembleCommand extends FlutterCommand { ...@@ -261,18 +262,19 @@ class AssembleCommand extends FlutterCommand {
final String value = chunk.substring(indexEquals + 1); final String value = chunk.substring(indexEquals + 1);
results[key] = value; results[key] = value;
} }
if (argResults.wasParsed(FlutterOptions.kExtraGenSnapshotOptions)) { final ArgResults argumentResults = argResults!;
results[kExtraGenSnapshotOptions] = (argResults[FlutterOptions.kExtraGenSnapshotOptions] as List<String>).join(','); if (argumentResults.wasParsed(FlutterOptions.kExtraGenSnapshotOptions)) {
results[kExtraGenSnapshotOptions] = (argumentResults[FlutterOptions.kExtraGenSnapshotOptions] as List<String>).join(',');
} }
if (argResults.wasParsed(FlutterOptions.kDartDefinesOption)) { if (argumentResults.wasParsed(FlutterOptions.kDartDefinesOption)) {
results[kDartDefines] = (argResults[FlutterOptions.kDartDefinesOption] as List<String>).join(','); results[kDartDefines] = (argumentResults[FlutterOptions.kDartDefinesOption] as List<String>).join(',');
} }
results[kDeferredComponents] = 'false'; results[kDeferredComponents] = 'false';
if (FlutterProject.current().manifest.deferredComponents != null && isDeferredComponentsTargets() && !isDebug()) { if (FlutterProject.current().manifest.deferredComponents != null && isDeferredComponentsTargets() && !isDebug()) {
results[kDeferredComponents] = 'true'; results[kDeferredComponents] = 'true';
} }
if (argResults.wasParsed(FlutterOptions.kExtraFrontEndOptions)) { if (argumentResults.wasParsed(FlutterOptions.kExtraFrontEndOptions)) {
results[kExtraFrontEndOptions] = (argResults[FlutterOptions.kExtraFrontEndOptions] as List<String>).join(','); results[kExtraFrontEndOptions] = (argumentResults[FlutterOptions.kExtraFrontEndOptions] as List<String>).join(',');
} }
return results; return results;
} }
...@@ -289,7 +291,7 @@ class AssembleCommand extends FlutterCommand { ...@@ -289,7 +291,7 @@ class AssembleCommand extends FlutterCommand {
nonDeferredTargets.add(target); nonDeferredTargets.add(target);
} }
} }
Target target; Target? target;
List<String> decodedDefines; List<String> decodedDefines;
try { try {
decodedDefines = decodeDartDefines(environment.defines, kDartDefines); decodedDefines = decodeDartDefines(environment.defines, kDartDefines);
...@@ -314,12 +316,13 @@ class AssembleCommand extends FlutterCommand { ...@@ -314,12 +316,13 @@ class AssembleCommand extends FlutterCommand {
} else if (targets.isNotEmpty) { } else if (targets.isNotEmpty) {
target = targets.single; target = targets.single;
} }
final ArgResults argumentResults = argResults!;
final BuildResult result = await _buildSystem.build( final BuildResult result = await _buildSystem.build(
target, target!,
environment, environment,
buildSystemConfig: BuildSystemConfig( buildSystemConfig: BuildSystemConfig(
resourcePoolSize: argResults.wasParsed('resource-pool-size') resourcePoolSize: argumentResults.wasParsed('resource-pool-size')
? int.tryParse(stringArg('resource-pool-size')) ? int.tryParse(stringArg('resource-pool-size')!)
: null, : null,
), ),
); );
...@@ -335,17 +338,17 @@ class AssembleCommand extends FlutterCommand { ...@@ -335,17 +338,17 @@ class AssembleCommand extends FlutterCommand {
} }
globals.printTrace('build succeeded.'); globals.printTrace('build succeeded.');
if (argResults.wasParsed('build-inputs')) { if (argumentResults.wasParsed('build-inputs')) {
writeListIfChanged(result.inputFiles, stringArg('build-inputs')); writeListIfChanged(result.inputFiles, stringArg('build-inputs')!);
} }
if (argResults.wasParsed('build-outputs')) { if (argumentResults.wasParsed('build-outputs')) {
writeListIfChanged(result.outputFiles, stringArg('build-outputs')); writeListIfChanged(result.outputFiles, stringArg('build-outputs')!);
} }
if (argResults.wasParsed('performance-measurement-file')) { if (argumentResults.wasParsed('performance-measurement-file')) {
final File outFile = globals.fs.file(argResults['performance-measurement-file']); final File outFile = globals.fs.file(argumentResults['performance-measurement-file']);
writePerformanceData(result.performance.values, outFile); writePerformanceData(result.performance.values, outFile);
} }
if (argResults.wasParsed('depfile')) { if (argumentResults.wasParsed('depfile')) {
final File depfileFile = globals.fs.file(stringArg('depfile')); final File depfileFile = globals.fs.file(stringArg('depfile'));
final Depfile depfile = Depfile(result.inputFiles, result.outputFiles); final Depfile depfile = Depfile(result.inputFiles, result.outputFiles);
final DepfileService depfileService = DepfileService( final DepfileService depfileService = DepfileService(
......
...@@ -2,11 +2,8 @@ ...@@ -2,11 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
// @dart = 2.8
import 'dart:async'; import 'dart:async';
import 'package:meta/meta.dart';
import 'package:stream_channel/stream_channel.dart'; import 'package:stream_channel/stream_channel.dart';
import 'package:vm_service/vm_service.dart' as vm_service; import 'package:vm_service/vm_service.dart' as vm_service;
...@@ -24,10 +21,10 @@ const String kIntegrationTestMethod = 'ext.flutter.integrationTest'; ...@@ -24,10 +21,10 @@ const String kIntegrationTestMethod = 'ext.flutter.integrationTest';
class IntegrationTestTestDevice implements TestDevice { class IntegrationTestTestDevice implements TestDevice {
IntegrationTestTestDevice({ IntegrationTestTestDevice({
@required this.id, required this.id,
@required this.device, required this.device,
@required this.debuggingOptions, required this.debuggingOptions,
@required this.userIdentifier, required this.userIdentifier,
}); });
final int id; final int id;
...@@ -35,7 +32,7 @@ class IntegrationTestTestDevice implements TestDevice { ...@@ -35,7 +32,7 @@ class IntegrationTestTestDevice implements TestDevice {
final DebuggingOptions debuggingOptions; final DebuggingOptions debuggingOptions;
final String userIdentifier; final String userIdentifier;
ApplicationPackage _applicationPackage; ApplicationPackage? _applicationPackage;
final Completer<void> _finished = Completer<void>(); final Completer<void> _finished = Completer<void>();
final Completer<Uri> _gotProcessObservatoryUri = Completer<Uri>(); final Completer<Uri> _gotProcessObservatoryUri = Completer<Uri>();
...@@ -45,13 +42,16 @@ class IntegrationTestTestDevice implements TestDevice { ...@@ -45,13 +42,16 @@ class IntegrationTestTestDevice implements TestDevice {
@override @override
Future<StreamChannel<String>> start(String entrypointPath) async { Future<StreamChannel<String>> start(String entrypointPath) async {
final TargetPlatform targetPlatform = await device.targetPlatform; final TargetPlatform targetPlatform = await device.targetPlatform;
_applicationPackage = await ApplicationPackageFactory.instance.getPackageForPlatform( _applicationPackage = await ApplicationPackageFactory.instance?.getPackageForPlatform(
targetPlatform, targetPlatform,
buildInfo: debuggingOptions.buildInfo, buildInfo: debuggingOptions.buildInfo,
); );
if (_applicationPackage == null) {
throw TestDeviceException('No application found for $targetPlatform.', StackTrace.current);
}
final LaunchResult launchResult = await device.startApp( final LaunchResult launchResult = await device.startApp(
_applicationPackage, _applicationPackage!,
mainPath: entrypointPath, mainPath: entrypointPath,
platformArgs: <String, dynamic>{}, platformArgs: <String, dynamic>{},
debuggingOptions: debuggingOptions, debuggingOptions: debuggingOptions,
...@@ -60,17 +60,18 @@ class IntegrationTestTestDevice implements TestDevice { ...@@ -60,17 +60,18 @@ class IntegrationTestTestDevice implements TestDevice {
if (!launchResult.started) { if (!launchResult.started) {
throw TestDeviceException('Unable to start the app on the device.', StackTrace.current); throw TestDeviceException('Unable to start the app on the device.', StackTrace.current);
} }
if (launchResult.observatoryUri == null) { final Uri? observatoryUri = launchResult.observatoryUri;
if (observatoryUri == null) {
throw TestDeviceException('Observatory is not available on the test device.', StackTrace.current); throw TestDeviceException('Observatory is not available on the test device.', StackTrace.current);
} }
// No need to set up the log reader because the logs are captured and // No need to set up the log reader because the logs are captured and
// streamed to the package:test_core runner. // streamed to the package:test_core runner.
_gotProcessObservatoryUri.complete(launchResult.observatoryUri); _gotProcessObservatoryUri.complete(observatoryUri);
globals.printTrace('test $id: Connecting to vm service'); globals.printTrace('test $id: Connecting to vm service');
final FlutterVmService vmService = await connectToVmService(launchResult.observatoryUri, logger: globals.logger).timeout( final FlutterVmService vmService = await connectToVmService(observatoryUri, logger: globals.logger).timeout(
const Duration(seconds: 5), const Duration(seconds: 5),
onTimeout: () => throw TimeoutException('Connecting to the VM Service timed out.'), onTimeout: () => throw TimeoutException('Connecting to the VM Service timed out.'),
); );
...@@ -83,7 +84,7 @@ class IntegrationTestTestDevice implements TestDevice { ...@@ -83,7 +84,7 @@ class IntegrationTestTestDevice implements TestDevice {
await vmService.service.streamListen(vm_service.EventStreams.kExtension); await vmService.service.streamListen(vm_service.EventStreams.kExtension);
final Stream<String> remoteMessages = vmService.service.onExtensionEvent final Stream<String> remoteMessages = vmService.service.onExtensionEvent
.where((vm_service.Event e) => e.extensionKind == kIntegrationTestExtension) .where((vm_service.Event e) => e.extensionKind == kIntegrationTestExtension)
.map((vm_service.Event e) => e.extensionData.data[kIntegrationTestData] as String); .map((vm_service.Event e) => e.extensionData!.data[kIntegrationTestData] as String);
final StreamChannelController<String> controller = StreamChannelController<String>(); final StreamChannelController<String> controller = StreamChannelController<String>();
...@@ -113,12 +114,15 @@ class IntegrationTestTestDevice implements TestDevice { ...@@ -113,12 +114,15 @@ class IntegrationTestTestDevice implements TestDevice {
@override @override
Future<void> kill() async { Future<void> kill() async {
if (!await device.stopApp(_applicationPackage, userIdentifier: userIdentifier)) { final ApplicationPackage? applicationPackage = _applicationPackage;
if (applicationPackage != null) {
if (!await device.stopApp(applicationPackage, userIdentifier: userIdentifier)) {
globals.printTrace('Could not stop the Integration Test app.'); globals.printTrace('Could not stop the Integration Test app.');
} }
if (!await device.uninstallApp(_applicationPackage, userIdentifier: userIdentifier)) { if (!await device.uninstallApp(applicationPackage, userIdentifier: userIdentifier)) {
globals.printTrace('Could not uninstall the Integration Test app.'); globals.printTrace('Could not uninstall the Integration Test app.');
} }
}
await device.dispose(); await device.dispose();
_finished.complete(); _finished.complete();
......
...@@ -750,21 +750,6 @@ class FakeDevice extends Fake implements Device { ...@@ -750,21 +750,6 @@ class FakeDevice extends Fake implements Device {
} }
} }
class FakeApplicationPackageFactory extends Fake implements ApplicationPackageFactory {
FakeApplicationPackageFactory(this.applicationPackage);
ApplicationPackage applicationPackage;
@override
Future<ApplicationPackage> getPackageForPlatform(
TargetPlatform platform, {
BuildInfo buildInfo,
File applicationBinary,
}) async => applicationPackage;
}
class FakeApplicationPackage extends Fake implements ApplicationPackage { }
class TestRunCommandWithFakeResidentRunner extends RunCommand { class TestRunCommandWithFakeResidentRunner extends RunCommand {
FakeResidentRunner fakeResidentRunner; FakeResidentRunner fakeResidentRunner;
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
// @dart = 2.8 // @dart = 2.8
import 'package:file/file.dart';
import 'package:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/io.dart' as io; import 'package:flutter_tools/src/base/io.dart' as io;
import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart'; import 'package:flutter_tools/src/build_info.dart';
...@@ -12,8 +14,10 @@ import 'package:flutter_tools/src/test/integration_test_device.dart'; ...@@ -12,8 +14,10 @@ import 'package:flutter_tools/src/test/integration_test_device.dart';
import 'package:flutter_tools/src/test/test_device.dart'; import 'package:flutter_tools/src/test/test_device.dart';
import 'package:flutter_tools/src/vmservice.dart'; import 'package:flutter_tools/src/vmservice.dart';
import 'package:stream_channel/stream_channel.dart'; import 'package:stream_channel/stream_channel.dart';
import 'package:test/fake.dart';
import 'package:vm_service/vm_service.dart' as vm_service; import 'package:vm_service/vm_service.dart' as vm_service;
import '../src/common.dart';
import '../src/context.dart'; import '../src/context.dart';
import '../src/fake_devices.dart'; import '../src/fake_devices.dart';
import '../src/fake_vm_services.dart'; import '../src/fake_vm_services.dart';
...@@ -121,12 +125,26 @@ void main() { ...@@ -121,12 +125,26 @@ void main() {
]); ]);
}); });
testUsingContext('will not start when package missing', () async {
await expectLater(
testDevice.start('entrypointPath'),
throwsA(
isA<TestDeviceException>().having(
(Exception e) => e.toString(),
'description',
contains('No application found for TargetPlatform.android_arm'),
),
),
);
});
testUsingContext('Can start the entrypoint', () async { testUsingContext('Can start the entrypoint', () async {
await testDevice.start('entrypointPath'); await testDevice.start('entrypointPath');
expect(await testDevice.observatoryUri, observatoryUri); expect(await testDevice.observatoryUri, observatoryUri);
expect(testDevice.finished, doesNotComplete); expect(testDevice.finished, doesNotComplete);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
VMServiceConnector: () => (Uri httpUri, { VMServiceConnector: () => (Uri httpUri, {
ReloadSources reloadSources, ReloadSources reloadSources,
Restart restart, Restart restart,
...@@ -145,6 +163,7 @@ void main() { ...@@ -145,6 +163,7 @@ void main() {
expect(testDevice.finished, completes); expect(testDevice.finished, completes);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
VMServiceConnector: () => (Uri httpUri, { VMServiceConnector: () => (Uri httpUri, {
ReloadSources reloadSources, ReloadSources reloadSources,
Restart restart, Restart restart,
...@@ -218,6 +237,7 @@ void main() { ...@@ -218,6 +237,7 @@ void main() {
await fakeVmServiceHost.vmService.dispose(); await fakeVmServiceHost.vmService.dispose();
expect(await channel.stream.isEmpty, true); expect(await channel.stream.isEmpty, true);
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
VMServiceConnector: () => (Uri httpUri, { VMServiceConnector: () => (Uri httpUri, {
ReloadSources reloadSources, ReloadSources reloadSources,
Restart restart, Restart restart,
...@@ -230,3 +250,14 @@ void main() { ...@@ -230,3 +250,14 @@ void main() {
}) async => fakeVmServiceHost.vmService, }) async => fakeVmServiceHost.vmService,
}); });
} }
class FakeApplicationPackageFactory extends Fake implements ApplicationPackageFactory {
@override
Future<ApplicationPackage> getPackageForPlatform(
TargetPlatform platform, {
BuildInfo buildInfo,
File applicationBinary,
}) async => FakeApplicationPackage();
}
class FakeApplicationPackage extends Fake implements ApplicationPackage { }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment