mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
[flutter_tool] Improve Fuchsia 'run' tests (#33263)
This commit is contained in:
parent
7ec9a6fa72
commit
f5827f0f07
@ -4,6 +4,7 @@
|
||||
|
||||
import '../base/common.dart';
|
||||
import '../base/process.dart';
|
||||
import '../globals.dart';
|
||||
import 'fuchsia_sdk.dart';
|
||||
|
||||
// Usage: dev_finder <flags> <subcommand> <subcommand args>
|
||||
@ -31,7 +32,11 @@ class FuchsiaDevFinder {
|
||||
'-full'
|
||||
];
|
||||
final RunResult result = await runAsync(command);
|
||||
return (result.exitCode == 0) ? result.stdout.split('\n') : null;
|
||||
if (result.exitCode != 0) {
|
||||
printError('dev_finder failed: ${result.stderr}');
|
||||
return null;
|
||||
}
|
||||
return result.stdout.split('\n');
|
||||
}
|
||||
|
||||
/// Returns the host address by which the device [deviceName] should use for
|
||||
@ -51,6 +56,10 @@ class FuchsiaDevFinder {
|
||||
deviceName
|
||||
];
|
||||
final RunResult result = await runAsync(command);
|
||||
return (result.exitCode == 0) ? result.stdout.trim() : null;
|
||||
if (result.exitCode != 0) {
|
||||
printError('dev_finder failed: ${result.stderr}');
|
||||
return null;
|
||||
}
|
||||
return result.stdout.trim();
|
||||
}
|
||||
}
|
||||
|
@ -44,9 +44,6 @@ class FuchsiaDeviceTools {
|
||||
FuchsiaTilesCtl get tilesCtl => _tilesCtl ??= FuchsiaTilesCtl();
|
||||
}
|
||||
|
||||
final FuchsiaAmberCtl _amberCtl = fuchsiaDeviceTools.amberCtl;
|
||||
final FuchsiaTilesCtl _tilesCtl = fuchsiaDeviceTools.tilesCtl;
|
||||
|
||||
final String _ipv4Loopback = InternetAddress.loopbackIPv4.address;
|
||||
final String _ipv6Loopback = InternetAddress.loopbackIPv6.address;
|
||||
|
||||
@ -233,6 +230,10 @@ class FuchsiaDevice extends Device {
|
||||
await stopApp(package);
|
||||
// Find out who the device thinks we are.
|
||||
final String host = await fuchsiaSdk.fuchsiaDevFinder.resolve(name);
|
||||
if (host == null) {
|
||||
printError('Failed to resolve host for Fuchsia device');
|
||||
return LaunchResult.failed();
|
||||
}
|
||||
final int port = await os.findFreePort();
|
||||
if (port == 0) {
|
||||
printError('Failed to find a free port');
|
||||
@ -265,14 +266,14 @@ class FuchsiaDevice extends Device {
|
||||
}
|
||||
|
||||
// Teach amber about the package server.
|
||||
if (!await _amberCtl.addSrc(this, fuchsiaPackageServer)) {
|
||||
if (!await fuchsiaDeviceTools.amberCtl.addSrc(this, fuchsiaPackageServer)) {
|
||||
printError('Failed to teach amber about the package server');
|
||||
return LaunchResult.failed();
|
||||
}
|
||||
serverRegistered = true;
|
||||
|
||||
// Tell amber to prefetch the app.
|
||||
if (!await _amberCtl.getUp(this, appName)) {
|
||||
if (!await fuchsiaDeviceTools.amberCtl.getUp(this, appName)) {
|
||||
printError('Failed to get amber to prefetch the package');
|
||||
return LaunchResult.failed();
|
||||
}
|
||||
@ -286,14 +287,14 @@ class FuchsiaDevice extends Device {
|
||||
// Instruct tiles_ctl to start the app.
|
||||
final String fuchsiaUrl =
|
||||
'fuchsia-pkg://fuchsia.com/$appName#meta/$appName.cmx';
|
||||
if (!await _tilesCtl.add(this, fuchsiaUrl, <String>[])) {
|
||||
if (!await fuchsiaDeviceTools.tilesCtl.add(this, fuchsiaUrl, <String>[])) {
|
||||
printError('Failed to add the app to tiles');
|
||||
return LaunchResult.failed();
|
||||
}
|
||||
} finally {
|
||||
// Try to un-teach amber about the package server if needed.
|
||||
if (serverRegistered) {
|
||||
await _amberCtl.rmSrc(this, fuchsiaPackageServer);
|
||||
await fuchsiaDeviceTools.amberCtl.rmSrc(this, fuchsiaPackageServer);
|
||||
}
|
||||
// Shutdown the package server and delete the package repo;
|
||||
fuchsiaPackageServer.stop();
|
||||
@ -308,7 +309,7 @@ class FuchsiaDevice extends Device {
|
||||
|
||||
// In a debug or profile build, try to find the observatory uri.
|
||||
final FuchsiaIsolateDiscoveryProtocol discovery =
|
||||
FuchsiaIsolateDiscoveryProtocol(this, appName);
|
||||
getIsolateDiscoveryProtocol(appName);
|
||||
try {
|
||||
final Uri observatoryUri = await discovery.uri;
|
||||
return LaunchResult.succeeded(observatoryUri: observatoryUri);
|
||||
@ -321,7 +322,7 @@ class FuchsiaDevice extends Device {
|
||||
Future<bool> stopApp(covariant FuchsiaApp app) async {
|
||||
final int appKey = await FuchsiaTilesCtl.findAppKey(this, app.id);
|
||||
if (appKey != -1) {
|
||||
if (!await _tilesCtl.remove(this, appKey)) {
|
||||
if (!await fuchsiaDeviceTools.tilesCtl.remove(this, appKey)) {
|
||||
printError('tiles_ctl remove on ${app.id} failed.');
|
||||
return false;
|
||||
}
|
||||
|
@ -50,6 +50,9 @@ class FuchsiaSdk {
|
||||
return null;
|
||||
}
|
||||
final List<String> devices = await fuchsiaDevFinder.list();
|
||||
if (devices == null) {
|
||||
return null;
|
||||
}
|
||||
return devices.isNotEmpty ? devices[0] : null;
|
||||
}
|
||||
|
||||
|
@ -407,32 +407,49 @@ void main() {
|
||||
group('fuchsia app start and stop: ', () {
|
||||
MemoryFileSystem memoryFileSystem;
|
||||
MockOperatingSystemUtils osUtils;
|
||||
MockFuchsiaDeviceTools fuchsiaDeviceTools;
|
||||
FakeFuchsiaDeviceTools fuchsiaDeviceTools;
|
||||
MockFuchsiaSdk fuchsiaSdk;
|
||||
setUp(() {
|
||||
memoryFileSystem = MemoryFileSystem();
|
||||
osUtils = MockOperatingSystemUtils();
|
||||
fuchsiaDeviceTools = MockFuchsiaDeviceTools();
|
||||
fuchsiaDeviceTools = FakeFuchsiaDeviceTools();
|
||||
fuchsiaSdk = MockFuchsiaSdk();
|
||||
|
||||
when(osUtils.findFreePort()).thenAnswer((_) => Future<int>.value(12345));
|
||||
});
|
||||
|
||||
testUsingContext('start prebuilt app in release mode', () async {
|
||||
Future<LaunchResult> setupAndStartApp({
|
||||
@required bool prebuilt,
|
||||
@required BuildMode mode,
|
||||
}) async {
|
||||
const String appName = 'app_name';
|
||||
final FuchsiaDevice device = FuchsiaDevice('123');
|
||||
final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123');
|
||||
fs.directory('fuchsia').createSync(recursive: true);
|
||||
final File pubspecFile = fs.file('pubspec.yaml')..createSync();
|
||||
pubspecFile.writeAsStringSync('name: $appName');
|
||||
final File far = fs.file('app_name-0.far')..createSync();
|
||||
|
||||
final FuchsiaApp app = FuchsiaApp.fromPrebuiltApp(far);
|
||||
FuchsiaApp app;
|
||||
if (prebuilt) {
|
||||
final File far = fs.file('app_name-0.far')..createSync();
|
||||
app = FuchsiaApp.fromPrebuiltApp(far);
|
||||
} else {
|
||||
fs.file(fs.path.join('fuchsia', 'meta', '$appName.cmx'))
|
||||
.createSync(recursive: true);
|
||||
fs.file('.packages').createSync();
|
||||
fs.file(fs.path.join('lib', 'main.dart')).createSync(recursive: true);
|
||||
app = BuildableFuchsiaApp(project: FlutterProject.current().fuchsia);
|
||||
}
|
||||
|
||||
final DebuggingOptions debuggingOptions =
|
||||
DebuggingOptions.disabled(const BuildInfo(BuildMode.release, null));
|
||||
final LaunchResult launchResult = await device.startApp(app,
|
||||
prebuiltApplication: true,
|
||||
DebuggingOptions.disabled(BuildInfo(mode, null));
|
||||
return await device.startApp(app,
|
||||
prebuiltApplication: prebuilt,
|
||||
debuggingOptions: debuggingOptions);
|
||||
}
|
||||
|
||||
testUsingContext('start prebuilt in release mode', () async {
|
||||
final LaunchResult launchResult =
|
||||
await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
|
||||
expect(launchResult.started, isTrue);
|
||||
expect(launchResult.hasObservatory, isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
@ -442,9 +459,9 @@ void main() {
|
||||
OperatingSystemUtils: () => osUtils,
|
||||
});
|
||||
|
||||
testUsingContext('start and stop prebuilt app in release mode', () async {
|
||||
testUsingContext('start and stop prebuilt in release mode', () async {
|
||||
const String appName = 'app_name';
|
||||
final FuchsiaDevice device = FuchsiaDevice('123');
|
||||
final FuchsiaDevice device = FuchsiaDeviceWithFakeDiscovery('123');
|
||||
fs.directory('fuchsia').createSync(recursive: true);
|
||||
final File pubspecFile = fs.file('pubspec.yaml')..createSync();
|
||||
pubspecFile.writeAsStringSync('name: $appName');
|
||||
@ -456,7 +473,6 @@ void main() {
|
||||
final LaunchResult launchResult = await device.startApp(app,
|
||||
prebuiltApplication: true,
|
||||
debuggingOptions: debuggingOptions);
|
||||
|
||||
expect(launchResult.started, isTrue);
|
||||
expect(launchResult.hasObservatory, isFalse);
|
||||
expect(await device.stopApp(app), isTrue);
|
||||
@ -466,6 +482,91 @@ void main() {
|
||||
FuchsiaSdk: () => fuchsiaSdk,
|
||||
OperatingSystemUtils: () => osUtils,
|
||||
});
|
||||
|
||||
testUsingContext('start prebuilt in debug mode', () async {
|
||||
final LaunchResult launchResult =
|
||||
await setupAndStartApp(prebuilt: true, mode: BuildMode.debug);
|
||||
expect(launchResult.started, isTrue);
|
||||
expect(launchResult.hasObservatory, isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => memoryFileSystem,
|
||||
FuchsiaDeviceTools: () => fuchsiaDeviceTools,
|
||||
FuchsiaSdk: () => fuchsiaSdk,
|
||||
OperatingSystemUtils: () => osUtils,
|
||||
});
|
||||
|
||||
testUsingContext('start buildable in release mode', () async {
|
||||
final LaunchResult launchResult =
|
||||
await setupAndStartApp(prebuilt: false, mode: BuildMode.release);
|
||||
expect(launchResult.started, isTrue);
|
||||
expect(launchResult.hasObservatory, isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => memoryFileSystem,
|
||||
FuchsiaDeviceTools: () => fuchsiaDeviceTools,
|
||||
FuchsiaSdk: () => fuchsiaSdk,
|
||||
OperatingSystemUtils: () => osUtils,
|
||||
});
|
||||
|
||||
testUsingContext('start buildable in debug mode', () async {
|
||||
final LaunchResult launchResult =
|
||||
await setupAndStartApp(prebuilt: false, mode: BuildMode.debug);
|
||||
expect(launchResult.started, isTrue);
|
||||
expect(launchResult.hasObservatory, isTrue);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => memoryFileSystem,
|
||||
FuchsiaDeviceTools: () => fuchsiaDeviceTools,
|
||||
FuchsiaSdk: () => fuchsiaSdk,
|
||||
OperatingSystemUtils: () => osUtils,
|
||||
});
|
||||
|
||||
testUsingContext('fail with correct LaunchResult when dev_finder fails', () async {
|
||||
final LaunchResult launchResult =
|
||||
await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
|
||||
expect(launchResult.started, isFalse);
|
||||
expect(launchResult.hasObservatory, isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => memoryFileSystem,
|
||||
FuchsiaDeviceTools: () => fuchsiaDeviceTools,
|
||||
FuchsiaSdk: () => MockFuchsiaSdk(devFinder: FailingDevFinder()),
|
||||
OperatingSystemUtils: () => osUtils,
|
||||
});
|
||||
|
||||
testUsingContext('fail with correct LaunchResult when pm fails', () async {
|
||||
final LaunchResult launchResult =
|
||||
await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
|
||||
expect(launchResult.started, isFalse);
|
||||
expect(launchResult.hasObservatory, isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => memoryFileSystem,
|
||||
FuchsiaDeviceTools: () => fuchsiaDeviceTools,
|
||||
FuchsiaSdk: () => MockFuchsiaSdk(pm: FailingPM()),
|
||||
OperatingSystemUtils: () => osUtils,
|
||||
});
|
||||
|
||||
testUsingContext('fail with correct LaunchResult when amber fails', () async {
|
||||
final LaunchResult launchResult =
|
||||
await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
|
||||
expect(launchResult.started, isFalse);
|
||||
expect(launchResult.hasObservatory, isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => memoryFileSystem,
|
||||
FuchsiaDeviceTools: () => FakeFuchsiaDeviceTools(amber: FailingAmberCtl()),
|
||||
FuchsiaSdk: () => fuchsiaSdk,
|
||||
OperatingSystemUtils: () => osUtils,
|
||||
});
|
||||
|
||||
testUsingContext('fail with correct LaunchResult when tiles fails', () async {
|
||||
final LaunchResult launchResult =
|
||||
await setupAndStartApp(prebuilt: true, mode: BuildMode.release);
|
||||
expect(launchResult.started, isFalse);
|
||||
expect(launchResult.hasObservatory, isFalse);
|
||||
}, overrides: <Type, Generator>{
|
||||
FileSystem: () => memoryFileSystem,
|
||||
FuchsiaDeviceTools: () => FakeFuchsiaDeviceTools(tiles: FailingTilesCtl()),
|
||||
FuchsiaSdk: () => fuchsiaSdk,
|
||||
OperatingSystemUtils: () => osUtils,
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -559,7 +660,24 @@ class MockIsolate extends Mock implements Isolate {
|
||||
final String name;
|
||||
}
|
||||
|
||||
class MockFuchsiaAmberCtl extends Mock implements FuchsiaAmberCtl {
|
||||
class FuchsiaDeviceWithFakeDiscovery extends FuchsiaDevice {
|
||||
FuchsiaDeviceWithFakeDiscovery(String id, {String name}) : super(id, name: name);
|
||||
|
||||
@override
|
||||
FuchsiaIsolateDiscoveryProtocol getIsolateDiscoveryProtocol(
|
||||
String isolateName) =>
|
||||
FakeFuchsiaIsolateDiscoveryProtocol();
|
||||
}
|
||||
|
||||
class FakeFuchsiaIsolateDiscoveryProtocol implements FuchsiaIsolateDiscoveryProtocol {
|
||||
@override
|
||||
FutureOr<Uri> get uri => Uri.parse('http://[::1]:37');
|
||||
|
||||
@override
|
||||
void dispose() {}
|
||||
}
|
||||
|
||||
class FakeFuchsiaAmberCtl implements FuchsiaAmberCtl {
|
||||
@override
|
||||
Future<bool> addSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
|
||||
return true;
|
||||
@ -576,7 +694,24 @@ class MockFuchsiaAmberCtl extends Mock implements FuchsiaAmberCtl {
|
||||
}
|
||||
}
|
||||
|
||||
class MockFuchsiaTilesCtl extends Mock implements FuchsiaTilesCtl {
|
||||
class FailingAmberCtl implements FuchsiaAmberCtl {
|
||||
@override
|
||||
Future<bool> addSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> rmSrc(FuchsiaDevice device, FuchsiaPackageServer server) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> getUp(FuchsiaDevice device, String packageName) async {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class FakeFuchsiaTilesCtl implements FuchsiaTilesCtl {
|
||||
final Map<int, String> _runningApps = <int, String>{};
|
||||
bool _started = false;
|
||||
int _nextAppId = 1;
|
||||
@ -624,15 +759,48 @@ class MockFuchsiaTilesCtl extends Mock implements FuchsiaTilesCtl {
|
||||
}
|
||||
}
|
||||
|
||||
class MockFuchsiaDeviceTools extends Mock implements FuchsiaDeviceTools {
|
||||
class FailingTilesCtl implements FuchsiaTilesCtl {
|
||||
@override
|
||||
final FuchsiaAmberCtl amberCtl = MockFuchsiaAmberCtl();
|
||||
Future<bool> start(FuchsiaDevice device) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
final FuchsiaTilesCtl tilesCtl = MockFuchsiaTilesCtl();
|
||||
Future<Map<int, String>> list(FuchsiaDevice device) async {
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> add(FuchsiaDevice device, String url, List<String> args) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> remove(FuchsiaDevice device, int key) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> quit(FuchsiaDevice device) async {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class MockFuchsiaPM extends Mock implements FuchsiaPM {
|
||||
class FakeFuchsiaDeviceTools implements FuchsiaDeviceTools {
|
||||
FakeFuchsiaDeviceTools({
|
||||
FuchsiaAmberCtl amber,
|
||||
FuchsiaTilesCtl tiles,
|
||||
}) : amberCtl = amber ?? FakeFuchsiaAmberCtl(),
|
||||
tilesCtl = tiles ?? FakeFuchsiaTilesCtl();
|
||||
|
||||
@override
|
||||
final FuchsiaAmberCtl amberCtl;
|
||||
|
||||
@override
|
||||
final FuchsiaTilesCtl tilesCtl;
|
||||
}
|
||||
|
||||
class FakeFuchsiaPM implements FuchsiaPM {
|
||||
String _appName;
|
||||
|
||||
@override
|
||||
@ -710,7 +878,46 @@ class MockFuchsiaPM extends Mock implements FuchsiaPM {
|
||||
}
|
||||
}
|
||||
|
||||
class MockFuchsiaKernelCompiler extends Mock implements FuchsiaKernelCompiler {
|
||||
class FailingPM implements FuchsiaPM {
|
||||
@override
|
||||
Future<bool> init(String buildPath, String appName) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> genkey(String buildPath, String outKeyPath) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> build(
|
||||
String buildPath, String keyPath, String manifestPath) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> archive(
|
||||
String buildPath, String keyPath, String manifestPath) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> newrepo(String repoPath) async {
|
||||
return false;
|
||||
}
|
||||
|
||||
@override
|
||||
Future<Process> serve(String repoPath, String host, int port) async {
|
||||
return _createMockProcess(exitCode: 6);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<bool> publish(String repoPath, String packagePath) async {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class FakeFuchsiaKernelCompiler implements FuchsiaKernelCompiler {
|
||||
@override
|
||||
Future<void> build({
|
||||
@required FuchsiaProject fuchsiaProject,
|
||||
@ -724,7 +931,18 @@ class MockFuchsiaKernelCompiler extends Mock implements FuchsiaKernelCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
class MockFuchsiaDevFinder extends Mock implements FuchsiaDevFinder {
|
||||
class FailingKernelCompiler implements FuchsiaKernelCompiler {
|
||||
@override
|
||||
Future<void> build({
|
||||
@required FuchsiaProject fuchsiaProject,
|
||||
@required String target, // E.g., lib/main.dart
|
||||
BuildInfo buildInfo = BuildInfo.debug,
|
||||
}) async {
|
||||
throwToolExit('Build process failed');
|
||||
}
|
||||
}
|
||||
|
||||
class FakeFuchsiaDevFinder implements FuchsiaDevFinder {
|
||||
@override
|
||||
Future<List<String>> list() async {
|
||||
return <String>['192.168.42.172 scare-cable-skip-joy'];
|
||||
@ -736,14 +954,33 @@ class MockFuchsiaDevFinder extends Mock implements FuchsiaDevFinder {
|
||||
}
|
||||
}
|
||||
|
||||
class MockFuchsiaSdk extends Mock implements FuchsiaSdk {
|
||||
class FailingDevFinder implements FuchsiaDevFinder {
|
||||
@override
|
||||
final FuchsiaPM fuchsiaPM = MockFuchsiaPM();
|
||||
Future<List<String>> list() async {
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
final FuchsiaKernelCompiler fuchsiaKernelCompiler =
|
||||
MockFuchsiaKernelCompiler();
|
||||
|
||||
@override
|
||||
final FuchsiaDevFinder fuchsiaDevFinder = MockFuchsiaDevFinder();
|
||||
Future<String> resolve(String deviceName) async {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class MockFuchsiaSdk extends Mock implements FuchsiaSdk {
|
||||
MockFuchsiaSdk({
|
||||
FuchsiaPM pm,
|
||||
FuchsiaKernelCompiler compiler,
|
||||
FuchsiaDevFinder devFinder,
|
||||
}) : fuchsiaPM = pm ?? FakeFuchsiaPM(),
|
||||
fuchsiaKernelCompiler = compiler ?? FakeFuchsiaKernelCompiler(),
|
||||
fuchsiaDevFinder = devFinder ?? FakeFuchsiaDevFinder();
|
||||
|
||||
@override
|
||||
final FuchsiaPM fuchsiaPM;
|
||||
|
||||
@override
|
||||
final FuchsiaKernelCompiler fuchsiaKernelCompiler;
|
||||
|
||||
@override
|
||||
final FuchsiaDevFinder fuchsiaDevFinder;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user