blob: ef0fb741aaa86fa0567d3478d65b9f3fcf2fec7e [file] [log] [blame]
// 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:flutter_tools/src/application_package.dart';
import 'package:flutter_tools/src/base/io.dart' as io;
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/device.dart';
import 'package:flutter_tools/src/test/integration_test_device.dart';
import 'package:flutter_tools/src/test/test_device.dart';
import 'package:flutter_tools/src/vmservice.dart';
import 'package:stream_channel/stream_channel.dart';
import 'package:test/fake.dart';
import 'package:vm_service/vm_service.dart' as vm_service;
import '../src/context.dart';
import '../src/fake_devices.dart';
import '../src/fake_vm_services.dart';
final vm_service.Isolate isolate = vm_service.Isolate(
id: '1',
pauseEvent: vm_service.Event(
kind: vm_service.EventKind.kResume,
timestamp: 0
),
breakpoints: <vm_service.Breakpoint>[],
libraries: <vm_service.LibraryRef>[
vm_service.LibraryRef(
id: '1',
uri: 'file:///hello_world/main.dart',
name: '',
),
],
livePorts: 0,
name: 'test',
number: '1',
pauseOnExit: false,
runnable: true,
startTime: 0,
isSystemIsolate: false,
isolateFlags: <vm_service.IsolateFlag>[],
extensionRPCs: <String>[kIntegrationTestMethod],
);
final FlutterView fakeFlutterView = FlutterView(
id: 'a',
uiIsolate: isolate,
);
final FakeVmServiceRequest listViewsRequest = FakeVmServiceRequest(
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[
fakeFlutterView.toJson(),
],
},
);
final Uri observatoryUri = Uri.parse('http://localhost:1234');
void main() {
late FakeVmServiceHost fakeVmServiceHost;
late TestDevice testDevice;
setUp(() {
testDevice = IntegrationTestTestDevice(
id: 1,
device: FakeDevice(
'ephemeral',
'ephemeral',
type: PlatformType.android,
launchResult: LaunchResult.succeeded(observatoryUri: observatoryUri),
),
debuggingOptions: DebuggingOptions.enabled(
BuildInfo.debug,
),
userIdentifier: '',
);
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
const FakeVmServiceRequest(
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate',
},
),
listViewsRequest,
FakeVmServiceRequest(
method: 'getIsolate',
jsonResponse: isolate.toJson(),
args: <String, Object>{
'isolateId': '1',
},
),
const FakeVmServiceRequest(
method: 'streamCancel',
args: <String, Object>{
'streamId': 'Isolate',
},
),
const FakeVmServiceRequest(
method: 'streamListen',
args: <String, Object>{
'streamId': 'Extension',
},
),
]);
});
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 {
await testDevice.start('entrypointPath');
expect(await testDevice.observatoryUri, observatoryUri);
expect(testDevice.finished, doesNotComplete);
}, overrides: <Type, Generator>{
ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
VMServiceConnector: () => (Uri httpUri, {
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
Logger? logger,
}) async => fakeVmServiceHost.vmService,
});
testUsingContext('Can kill the started device', () async {
await testDevice.start('entrypointPath');
await testDevice.kill();
expect(testDevice.finished, completes);
}, overrides: <Type, Generator>{
ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
VMServiceConnector: () => (Uri httpUri, {
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
Logger? logger,
}) async => fakeVmServiceHost.vmService,
});
testUsingContext('when the device starts without providing an observatory URI', () async {
final TestDevice testDevice = IntegrationTestTestDevice(
id: 1,
device: FakeDevice(
'ephemeral',
'ephemeral',
type: PlatformType.android,
launchResult: LaunchResult.succeeded(),
),
debuggingOptions: DebuggingOptions.enabled(
BuildInfo.debug,
),
userIdentifier: '',
);
expect(() => testDevice.start('entrypointPath'), throwsA(isA<TestDeviceException>()));
}, overrides: <Type, Generator>{
VMServiceConnector: () => (Uri httpUri, {
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
}) async => fakeVmServiceHost.vmService,
});
testUsingContext('when the device fails to start', () async {
final TestDevice testDevice = IntegrationTestTestDevice(
id: 1,
device: FakeDevice(
'ephemeral',
'ephemeral',
type: PlatformType.android,
launchResult: LaunchResult.failed(),
),
debuggingOptions: DebuggingOptions.enabled(
BuildInfo.debug,
),
userIdentifier: '',
);
expect(() => testDevice.start('entrypointPath'), throwsA(isA<TestDeviceException>()));
}, overrides: <Type, Generator>{
VMServiceConnector: () => (Uri httpUri, {
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
}) async => fakeVmServiceHost.vmService,
});
testUsingContext('Can handle closing of the VM service', () async {
final StreamChannel<String> channel = await testDevice.start('entrypointPath');
await fakeVmServiceHost.vmService.dispose();
expect(await channel.stream.isEmpty, true);
}, overrides: <Type, Generator>{
ApplicationPackageFactory: () => FakeApplicationPackageFactory(),
VMServiceConnector: () => (Uri httpUri, {
ReloadSources? reloadSources,
Restart? restart,
CompileExpression? compileExpression,
GetSkSLMethod? getSkSLMethod,
PrintStructuredErrorLogMethod? printStructuredErrorLogMethod,
io.CompressionOptions? compression,
Device? device,
Logger? logger,
}) 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 { }