mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

The tool needs to start outputing trace text to stderr to avoid breaking machine mode. This test is bogus, and should use the exit code.
163 lines
5.9 KiB
Dart
163 lines
5.9 KiB
Dart
// 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 'dart:async';
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:path/path.dart' as path;
|
|
import 'package:vm_service_client/vm_service_client.dart';
|
|
|
|
import 'package:flutter_devicelab/framework/adb.dart';
|
|
import 'package:flutter_devicelab/framework/framework.dart';
|
|
import 'package:flutter_devicelab/framework/utils.dart';
|
|
|
|
void main() {
|
|
Map<String, dynamic> parseFlutterResponse(String line) {
|
|
if (line.startsWith('[') && line.endsWith(']')) {
|
|
try {
|
|
return json.decode(line)[0] as Map<String, dynamic>;
|
|
} catch (e) {
|
|
// Not valid JSON, so likely some other output that was surrounded by [brackets]
|
|
return null;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Stream<String> transformToLines(Stream<List<int>> byteStream) {
|
|
return byteStream.transform<String>(utf8.decoder).transform<String>(const LineSplitter());
|
|
}
|
|
|
|
task(() async {
|
|
Uri vmServiceUri;
|
|
String appId;
|
|
|
|
final Device device = await devices.workingDevice;
|
|
await device.unlock();
|
|
final Directory appDir =
|
|
dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
|
|
await inDirectory(appDir, () async {
|
|
final Completer<void> ready = Completer<void>();
|
|
bool ok;
|
|
print('run: starting...');
|
|
final Process run = await startProcess(
|
|
path.join(flutterDirectory.path, 'bin', 'flutter'),
|
|
<String>[
|
|
'run',
|
|
'--machine',
|
|
'--no-fast-start',
|
|
'-d',
|
|
device.deviceId,
|
|
'lib/commands.dart',
|
|
],
|
|
);
|
|
final StreamController<String> stdout = StreamController<String>.broadcast();
|
|
transformToLines(run.stdout).listen((String line) {
|
|
print('run:stdout: $line');
|
|
stdout.add(line);
|
|
final dynamic json = parseFlutterResponse(line);
|
|
if (json != null) {
|
|
if (json['event'] == 'app.debugPort') {
|
|
vmServiceUri = Uri.parse(json['params']['wsUri'] as String);
|
|
print('service protocol connection available at $vmServiceUri');
|
|
} else if (json['event'] == 'app.started') {
|
|
appId = json['params']['appId'] as String;
|
|
print('application identifier is $appId');
|
|
}
|
|
}
|
|
if (vmServiceUri != null && appId != null && !ready.isCompleted) {
|
|
print('run: ready!');
|
|
ready.complete();
|
|
ok ??= true;
|
|
}
|
|
});
|
|
run.exitCode.then<void>((int exitCode) {
|
|
ok = false;
|
|
});
|
|
await Future.any<dynamic>(<Future<dynamic>>[ready.future, run.exitCode]);
|
|
if (!ok)
|
|
throw 'Failed to run test app.';
|
|
|
|
final VMServiceClient client = VMServiceClient.connect(vmServiceUri);
|
|
|
|
int id = 1;
|
|
Future<Map<String, dynamic>> sendRequest(String method, dynamic params) async {
|
|
final int requestId = id++;
|
|
final Completer<Map<String, dynamic>> response = Completer<Map<String, dynamic>>();
|
|
final StreamSubscription<String> responseSubscription = stdout.stream.listen((String line) {
|
|
final Map<String, dynamic> json = parseFlutterResponse(line);
|
|
if (json != null && json['id'] == requestId)
|
|
response.complete(json);
|
|
});
|
|
final Map<String, dynamic> req = <String, dynamic>{
|
|
'id': requestId,
|
|
'method': method,
|
|
'params': params,
|
|
};
|
|
final String jsonEncoded = json.encode(<Map<String, dynamic>>[req]);
|
|
print('run:stdin: $jsonEncoded');
|
|
run.stdin.writeln(jsonEncoded);
|
|
final Map<String, dynamic> result = await response.future;
|
|
responseSubscription.cancel();
|
|
return result;
|
|
}
|
|
|
|
print('test: sending two hot reloads...');
|
|
final Future<dynamic> hotReload1 = sendRequest(
|
|
'app.restart',
|
|
<String, dynamic>{'appId': appId, 'fullRestart': false},
|
|
);
|
|
final Future<dynamic> hotReload2 = sendRequest(
|
|
'app.restart',
|
|
<String, dynamic>{'appId': appId, 'fullRestart': false},
|
|
);
|
|
final Future<List<dynamic>> reloadRequests = Future.wait<dynamic>(<Future<dynamic>>[
|
|
hotReload1,
|
|
hotReload2,
|
|
]);
|
|
final dynamic results = await Future.any<dynamic>(<Future<dynamic>>[
|
|
run.exitCode,
|
|
reloadRequests,
|
|
]);
|
|
|
|
if (!ok)
|
|
throw 'App failed or crashed during hot reloads.';
|
|
|
|
final List<dynamic> responses = results as List<dynamic>;
|
|
final List<dynamic> errorResponses = responses.where(
|
|
(dynamic r) => r['error'] != null
|
|
).toList();
|
|
final List<dynamic> successResponses = responses.where(
|
|
(dynamic r) => r['error'] == null &&
|
|
r['result'] != null &&
|
|
r['result']['code'] == 0
|
|
).toList();
|
|
|
|
if (errorResponses.length != 1)
|
|
throw 'Did not receive the expected (exactly one) hot reload error response.';
|
|
final String errorMessage = (errorResponses.first as Map<String, dynamic>)['error'] as String;
|
|
if (!errorMessage.contains('in progress'))
|
|
throw 'Error response was not that hot reload was in progress.';
|
|
if (successResponses.length != 1)
|
|
throw 'Did not receive the expected (exactly one) successful hot reload response.';
|
|
|
|
final dynamic hotReload3 = await sendRequest(
|
|
'app.restart',
|
|
<String, dynamic>{'appId': appId, 'fullRestart': false},
|
|
);
|
|
if (hotReload3['error'] != null)
|
|
throw 'Received an error response from a hot reload after all other hot reloads had completed.';
|
|
|
|
sendRequest('app.stop', <String, dynamic>{'appId': appId});
|
|
final int result = await run.exitCode;
|
|
if (result != 0)
|
|
throw 'Received unexpected exit code $result from run process.';
|
|
print('test: validating that the app has in fact closed...');
|
|
await client.done;
|
|
});
|
|
return TaskResult.success(null);
|
|
});
|
|
}
|