Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add service manager tests and test_driver. #60

Merged
merged 49 commits into from
Dec 27, 2018
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
4e9bd8c
Add service manager tests and test_driver.
kenzieschmoll Dec 18, 2018
3168b4f
Polish async/await calls in EvalOnDartLibrary.
kenzieschmoll Dec 18, 2018
8c342a8
Add flutter_tools to pubspec.
kenzieschmoll Dec 18, 2018
95e0d55
Polish async/await flow in ServiceManager.
kenzieschmoll Dec 18, 2018
534dc31
Remove hot restart test case - will address in follow-up.
kenzieschmoll Dec 18, 2018
da50dff
formatting.
kenzieschmoll Dec 18, 2018
a051da0
fixes for service_manager_test
kenzieschmoll Dec 19, 2018
d0b3948
Add unawaited_futures lint and fix warnings.
kenzieschmoll Dec 19, 2018
7b00b65
make streamListen calls unawaited.
kenzieschmoll Dec 19, 2018
bcfdf48
Add necessary files from flutter_tools to support the use of FlutterT…
kenzieschmoll Dec 19, 2018
1dad05b
formatting
kenzieschmoll Dec 19, 2018
fd335f2
Use completer to await stream data.
kenzieschmoll Dec 19, 2018
df63642
Add flutter install to travis.sh.
kenzieschmoll Dec 19, 2018
d7fd09d
add flutter version check to travis script
kenzieschmoll Dec 19, 2018
12d24c4
Use curl to download flutter.
kenzieschmoll Dec 20, 2018
b8f6d52
edit download destination.
kenzieschmoll Dec 20, 2018
4648acc
debugging - add ls command
kenzieschmoll Dec 20, 2018
dac8167
change path to tar file
kenzieschmoll Dec 20, 2018
1941646
use relative path to flutter bin
kenzieschmoll Dec 20, 2018
60a21de
add pwd
kenzieschmoll Dec 20, 2018
6ab33bf
debugging
kenzieschmoll Dec 20, 2018
6906128
use macos flutter link
kenzieschmoll Dec 20, 2018
981b07b
use language generic
kenzieschmoll Dec 20, 2018
25b63ae
debugging
kenzieschmoll Dec 20, 2018
88f2137
point to flutter pub
kenzieschmoll Dec 20, 2018
2b5c4a0
update path
kenzieschmoll Dec 20, 2018
d0446b6
use flutter sdk conditionally
kenzieschmoll Dec 20, 2018
cba07e2
make which dart command consistent
kenzieschmoll Dec 20, 2018
679d77a
add comment
kenzieschmoll Dec 20, 2018
bb58742
add print statements
kenzieschmoll Dec 20, 2018
89f5244
more print statements
kenzieschmoll Dec 20, 2018
6ce525f
prune test_driver. Reduce dependencies to two files.
kenzieschmoll Dec 21, 2018
21dd48e
Make flutter_test_driver work on its own. Add changes from Devon's PR…
kenzieschmoll Dec 27, 2018
28b7d2d
Install flutter in devtools parent dir.
kenzieschmoll Dec 27, 2018
31ffb78
Extract common travis.sh code. Fix flutter path.
kenzieschmoll Dec 27, 2018
f78acd0
debugging
kenzieschmoll Dec 27, 2018
20baf28
Test service_manager_test on VM only.
kenzieschmoll Dec 27, 2018
76d2502
Merge branch 'master' of github.com:kenzieschmoll/devtools into servi…
kenzieschmoll Dec 27, 2018
7f0c801
revert added awaits in test/src/chrome.dart
kenzieschmoll Dec 27, 2018
d3b5da4
await enabling log
kenzieschmoll Dec 27, 2018
eeb3a5a
comment out chrome test and add explanation.
kenzieschmoll Dec 27, 2018
a2964fc
await streamListen calls. Small fixes to travis.sh and travis.yaml
kenzieschmoll Dec 27, 2018
3d8eaa8
ran dartfmt on entire devtools/ dir.
kenzieschmoll Dec 27, 2018
689dc1d
Add USE_FLUTTER_SDK=false env back to travis.yml.
kenzieschmoll Dec 27, 2018
d86b0e8
remove travis env's. Running flutter sdk tests after others should so…
kenzieschmoll Dec 27, 2018
a905ff0
await all streamListen calls at once
kenzieschmoll Dec 27, 2018
dd2bc03
remove double quotes from test tags.
kenzieschmoll Dec 27, 2018
466f9e2
Revert "ran dartfmt on entire devtools/ dir."
kenzieschmoll Dec 27, 2018
38d8dc4
formatting
kenzieschmoll Dec 27, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions lib/eval_on_dart_library.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,15 @@ class EvalOnDartLibrary {

// TODO: do we need to dispose this subscription at some point? Where?
serviceManager.isolateManager
.getCurrentFlutterIsolate((IsolateRef isolate) {
.getCurrentFlutterIsolate((IsolateRef isolate) async {
await _initializeComplete;

if (_libraryRef.isCompleted) {
_libraryRef = new Completer<LibraryRef>();
}

if (isolate != null) {
_initialize(isolate.id);
_initializeComplete = _initialize(isolate.id);
}
});
}
Expand All @@ -32,24 +34,28 @@ class EvalOnDartLibrary {
final String libraryName;
final VmServiceWrapper service;
Completer<LibraryRef> _libraryRef;
Future<void> _initializeComplete;

String get isolateId => _isolateId;
String _isolateId;

Future<LibraryRef> get libraryRef => _libraryRef.future;
Completer allPendingRequestsDone;

void _initialize(String isolateId) async {
Future<void> _initialize(String isolateId) async {
_isolateId = isolateId;

try {
final Isolate isolate = await service.getIsolate(_isolateId);
for (LibraryRef library in isolate.libraries) {
if (library.uri == libraryName) {
assert(!_libraryRef.isCompleted);
_libraryRef.complete(library);
return;
}
}
assert(!_libraryRef.isCompleted);
_libraryRef.completeError('Library $libraryName not found');
} catch (e) {
_handleError(e);
}
Expand All @@ -71,12 +77,16 @@ class EvalOnDartLibrary {

try {
final LibraryRef libraryRef = await _libraryRef.future;
return await service.evaluate(
final result = await service.evaluate(
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved
_isolateId,
libraryRef.id,
expression,
scope: scope,
);
if (result is ErrorRef) {
throw result;
}
return result;
} catch (e) {
_handleError(e);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/framework/framework_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class FrameworkCore {
final VmServiceWrapper service =
await connect('localhost', port, finishedCompleter);
if (serviceManager != null) {
serviceManager.vmServiceOpened(service, finishedCompleter.future);
await serviceManager.vmServiceOpened(service, finishedCompleter.future);
}
} catch (e) {
print('Unable to connect to service on port $port');
Expand Down
93 changes: 55 additions & 38 deletions lib/service_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class ServiceConnectionManager {
_stateController.add(null);
_connectionAvailableController.add(service);

_isolateManager._initIsolates(vm.isolates);
await _isolateManager._initIsolates(vm.isolates);
service.onIsolateEvent.listen(_isolateManager._handleIsolateEvent);
service.onExtensionEvent
.listen(_serviceExtensionManager._handleExtensionEvent);
Expand Down Expand Up @@ -98,19 +98,16 @@ class ServiceConnectionManager {
}

class IsolateManager {
IsolateManager() {
_flutterIsolateController = new StreamController<IsolateRef>.broadcast();
_flutterIsolateController.onListen =
() => _flutterIsolateController.add(_flutterIsolate);
}

// TODO(kenzie): de-dupe logic between _selectedIsolate and _flutterIsolate.
List<IsolateRef> _isolates = <IsolateRef>[];
List<IsolateRef> _flutterIsolates = <IsolateRef>[];
IsolateRef _selectedIsolate;
IsolateRef _flutterIsolate;
VmServiceWrapper _service;
ServiceExtensionManager _serviceExtensionManager;

StreamController<IsolateRef> _flutterIsolateController;
final StreamController<IsolateRef> _flutterIsolateController =
new StreamController<IsolateRef>.broadcast();
final StreamController<IsolateRef> _isolateCreatedController =
new StreamController<IsolateRef>.broadcast();
final StreamController<IsolateRef> _isolateExitedController =
Expand All @@ -120,10 +117,15 @@ class IsolateManager {

List<IsolateRef> get isolates => new List<IsolateRef>.unmodifiable(_isolates);

IsolateRef get flutterIsolate => _flutterIsolate;

IsolateRef get selectedIsolate => _selectedIsolate;

Stream<IsolateRef> get onIsolateCreated => _isolateCreatedController.stream;

Stream<IsolateRef> get onFlutterIsolateChanged =>
_flutterIsolateController.stream;

Stream<IsolateRef> get onSelectedIsolateChanged =>
_selectedIsolateController.stream;

Expand All @@ -139,27 +141,33 @@ class IsolateManager {
}
}

void _initIsolates(List<IsolateRef> isolates) {
Future<void> _initIsolates(List<IsolateRef> isolates) async {
_isolates = isolates;
_initFlutterIsolate(isolates);
_flutterIsolates = isolates;
await _initFlutterIsolate(isolates);
if (_flutterIsolate != null) {
_flutterIsolateController.add(_flutterIsolate);
}
_selectedIsolate = _selectBestFirstIsolate(isolates);
if (_selectedIsolate != null) {
_isolateCreatedController.add(_selectedIsolate);
_selectedIsolateController.add(_selectedIsolate);
}
}

void _handleIsolateEvent(Event event) {
void _handleIsolateEvent(Event event) async {
if (event.kind == 'IsolateStart') {
_isolates.add(event.isolate);
_flutterIsolates.add(event.isolate);
_isolateCreatedController.add(event.isolate);
if (_selectedIsolate == null) {
_selectedIsolate = event.isolate;
_selectedIsolateController.add(event.isolate);
}
} else if (event.kind == 'ServiceExtensionAdded') {
// On hot restart, service extensions are added from here.
_serviceExtensionManager._maybeAddServiceExtension(event.extensionRPC);
await _serviceExtensionManager
._maybeAddServiceExtension(event.extensionRPC);

// Check to see if there is a new flutter isolate.
if (_flutterIsolate == null) {
Expand All @@ -169,13 +177,14 @@ class IsolateManager {
}
} else if (event.kind == 'IsolateExit') {
_isolates.remove(event.isolate);
_flutterIsolates.remove(event.isolate);
_isolateExitedController.add(event.isolate);
if (_selectedIsolate == event.isolate) {
_selectedIsolate = _isolates.isEmpty ? null : _isolates.first;
_selectedIsolateController.add(_selectedIsolate);
}
if (_flutterIsolate == event.isolate) {
_setFlutterIsolate(null);
_setFlutterIsolate(_flutterIsolates.isEmpty ? null : _flutterIsolates.first);
_serviceExtensionManager.resetAvailableExtensions();
}
}
Expand All @@ -198,7 +207,7 @@ class IsolateManager {
return extensionName.startsWith('ext.flutter.');
}

void _initFlutterIsolate(List<IsolateRef> isolates) async {
Future<void> _initFlutterIsolate(List<IsolateRef> isolates) async {
for (IsolateRef ref in isolates) {
// Populate flutter isolate info.
if (_flutterIsolate == null) {
Expand All @@ -214,7 +223,7 @@ class IsolateManager {
}
// On initial connection to running app, service extensions are added from
// here.
_serviceExtensionManager._addRegisteredExtensionRPCs(ref);
await _serviceExtensionManager._addRegisteredExtensionRPCs(ref);
}
}

Expand All @@ -227,7 +236,11 @@ class IsolateManager {
_flutterIsolateController.add(ref);
}

StreamSubscription<IsolateRef> getCurrentFlutterIsolate(Function onData) {
StreamSubscription<IsolateRef> getCurrentFlutterIsolate(
void onData(IsolateRef ref)) {
if (_flutterIsolate != null) {
onData(_flutterIsolate);
}
return _flutterIsolateController.stream.listen(onData);
}
}
Expand All @@ -236,7 +249,7 @@ class ServiceExtensionManager {
VmServiceWrapper _service;
IsolateManager _isolateManager;

bool firstFrameEventReceived = false;
bool _firstFrameEventReceived = false;

final Map<String, StreamController<bool>> _serviceExtensionController =
<String, StreamController<bool>>{};
Expand All @@ -252,7 +265,7 @@ class ServiceExtensionManager {
<String, ServiceExtensionState>{};

/// Temporarily stores service extensions that we need to add. We should not add
/// extensions until the first frame event has been received [firstFrameEventReceived].
/// extensions until the first frame event has been received [_firstFrameEventReceived].
final Set<String> _pendingServiceExtensions = Set<String>();

void _handleExtensionEvent(Event event) {
Expand All @@ -265,25 +278,27 @@ class ServiceExtensionManager {
}

void _onFrameEventReceived() {
if (firstFrameEventReceived) {
if (_firstFrameEventReceived) {
// The first frame event was already received.
return;
}
firstFrameEventReceived = true;
_firstFrameEventReceived = true;

_pendingServiceExtensions.forEach(_addServiceExtension);
_pendingServiceExtensions.clear();
}

void _addRegisteredExtensionRPCs(IsolateRef isolateRef) async {
Future<void> _addRegisteredExtensionRPCs(IsolateRef isolateRef) async {
if (_service == null) {
return;
}
final Isolate isolate = await _service.getIsolate(isolateRef.id);
if (isolate.extensionRPCs != null) {
isolate.extensionRPCs.forEach(_maybeAddServiceExtension);
for (String extension in isolate.extensionRPCs) {
await _maybeAddServiceExtension(extension);
};

if (!firstFrameEventReceived) {
if (!_firstFrameEventReceived) {
final EvalOnDartLibrary flutterLibrary = new EvalOnDartLibrary(
'package:flutter/src/widgets/binding.dart',
_service,
Expand All @@ -301,16 +316,16 @@ class ServiceExtensionManager {
}
}

void _maybeAddServiceExtension(String name) {
if (firstFrameEventReceived) {
Future<void> _maybeAddServiceExtension(String name) async {
if (_firstFrameEventReceived) {
assert(_pendingServiceExtensions.isEmpty);
_addServiceExtension(name);
await _addServiceExtension(name);
} else {
_pendingServiceExtensions.add(name);
}
}

void _addServiceExtension(String name) {
Future<void> _addServiceExtension(String name) async {
final StreamController<bool> streamController =
_getServiceExtensionController(name);

Expand All @@ -319,30 +334,30 @@ class ServiceExtensionManager {

// Restore any previously enabled states by calling their service extensions.
if (_enabledServiceExtensions.containsKey(name)) {
_callServiceExtension(name, _enabledServiceExtensions[name].value);
await _callServiceExtension(name, _enabledServiceExtensions[name].value);
}
}

void _callServiceExtension(String name, dynamic value) {
Future<void> _callServiceExtension(String name, dynamic value) async {
if (_service == null) {
return;
}

assert(value != null);
if (value is bool) {
_service.callServiceExtension(
await _service.callServiceExtension(
name,
isolateId: _isolateManager.selectedIsolate.id,
args: {'enabled': value},
);
} else if (value is String) {
_service.callServiceExtension(
await _service.callServiceExtension(
name,
isolateId: _isolateManager.selectedIsolate.id,
args: {'value': value},
);
} else if (value is double) {
_service.callServiceExtension(
await _service.callServiceExtension(
name,
isolateId: _isolateManager.selectedIsolate.id,
// The param name for a numeric service extension will be the last part
Expand All @@ -353,7 +368,7 @@ class ServiceExtensionManager {
}

void resetAvailableExtensions() {
firstFrameEventReceived = false;
_firstFrameEventReceived = false;
_serviceExtensions.clear();
_serviceExtensionController
.forEach((String name, StreamController<bool> stream) {
Expand All @@ -362,8 +377,9 @@ class ServiceExtensionManager {
}

/// Sets the state for a service extension and makes the call to the VMService.
void setServiceExtensionState(String name, bool enabled, dynamic value) {
_callServiceExtension(name, value);
Future<void> setServiceExtensionState(
String name, bool enabled, dynamic value) async {
await _callServiceExtension(name, value);

final StreamController<ServiceExtensionState> streamController =
_getServiceExtensionStateController(name);
Expand All @@ -378,14 +394,15 @@ class ServiceExtensionManager {
}
}

StreamSubscription<bool> hasServiceExtension(String name, Function onData) {
StreamSubscription<bool> hasServiceExtension(
String name, void onData(bool value)) {
final StreamController<bool> streamController =
_getServiceExtensionController(name);
return streamController.stream.listen(onData);
}

StreamSubscription<ServiceExtensionState> getServiceExtensionState(
String name, Function onData) {
String name, void onData(ServiceExtensionState state)) {
final StreamController<ServiceExtensionState> streamController =
_getServiceExtensionStateController(name);
return streamController.stream.listen(onData);
Expand Down Expand Up @@ -422,7 +439,7 @@ class ServiceExtensionManager {
/// extension name.
StreamController<T> _getStream<T>(
String name, Map<String, StreamController<T>> streams,
{@required Function onFirstListenerSubscribed}) {
{@required void onFirstListenerSubscribed()}) {
streams.putIfAbsent(
name,
() =>
Expand Down
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ dependencies:
dev_dependencies:
build_runner: 1.0.0
build_web_compilers: any
flutter_tools:
kenzieschmoll marked this conversation as resolved.
Show resolved Hide resolved
path: '../flutter/packages/flutter_tools'
test: ^1.0.0
webdev: 1.0.1
webkit_inspection_protocol: ^0.3.6
Loading