Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
342c6286
Unverified
Commit
342c6286
authored
May 13, 2020
by
Jia Hao
Committed by
GitHub
May 13, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Eagerly wait for the driver extension on FlutterDriver.connect() (#56428)
parent
4b814cf8
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
62 additions
and
46 deletions
+62
-46
vmservice_driver.dart
packages/flutter_driver/lib/src/driver/vmservice_driver.dart
+45
-45
flutter_driver_test.dart
packages/flutter_driver/test/flutter_driver_test.dart
+17
-1
No files found.
packages/flutter_driver/lib/src/driver/vmservice_driver.dart
View file @
342c6286
...
@@ -8,7 +8,6 @@ import 'dart:io';
...
@@ -8,7 +8,6 @@ import 'dart:io';
import
'package:file/file.dart'
as
f
;
import
'package:file/file.dart'
as
f
;
import
'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart'
as
fuchsia
;
import
'package:fuchsia_remote_debug_protocol/fuchsia_remote_debug_protocol.dart'
as
fuchsia
;
import
'package:json_rpc_2/error_code.dart'
as
error_code
;
import
'package:json_rpc_2/json_rpc_2.dart'
as
rpc
;
import
'package:json_rpc_2/json_rpc_2.dart'
as
rpc
;
import
'package:meta/meta.dart'
;
import
'package:meta/meta.dart'
;
import
'package:path/path.dart'
as
p
;
import
'package:path/path.dart'
as
p
;
...
@@ -150,11 +149,37 @@ class VMServiceFlutterDriver extends FlutterDriver {
...
@@ -150,11 +149,37 @@ class VMServiceFlutterDriver extends FlutterDriver {
}
}
/// Waits for a signal from the VM service that the extension is registered.
/// Waits for a signal from the VM service that the extension is registered.
/// Returns [_flutterExtensionMethodName]
///
Future
<
String
>
waitForServiceExtension
()
{
/// Looks at the list of loaded extensions for the current [isolateRef], as
return
isolate
.
onExtensionAdded
.
firstWhere
((
String
extension
)
{
/// well as the stream of added extensions.
return
extension
==
_flutterExtensionMethodName
;
Future
<
void
>
waitForServiceExtension
()
async
{
});
final
Future
<
void
>
extensionAlreadyAdded
=
isolateRef
.
loadRunnable
()
.
then
((
VMIsolate
isolate
)
async
{
if
(
isolate
.
extensionRpcs
.
contains
(
_flutterExtensionMethodName
))
{
return
;
}
// Never complete. Rely on the stream listener to find the service
// extension instead.
return
Completer
<
void
>().
future
;
});
final
Completer
<
void
>
extensionAdded
=
Completer
<
void
>();
StreamSubscription
<
String
>
isolateAddedSubscription
;
isolateAddedSubscription
=
isolate
.
onExtensionAdded
.
listen
(
(
String
extensionName
)
{
if
(
extensionName
==
_flutterExtensionMethodName
)
{
extensionAdded
.
complete
();
isolateAddedSubscription
.
cancel
();
}
},
onError:
extensionAdded
.
completeError
,
cancelOnError:
true
);
await
Future
.
any
(<
Future
<
void
>>[
extensionAlreadyAdded
,
extensionAdded
.
future
,
]);
}
}
/// Tells the Dart VM Service to notify us about "Isolate" events.
/// Tells the Dart VM Service to notify us about "Isolate" events.
...
@@ -174,25 +199,7 @@ class VMServiceFlutterDriver extends FlutterDriver {
...
@@ -174,25 +199,7 @@ class VMServiceFlutterDriver extends FlutterDriver {
if
(
isolate
.
pauseEvent
is
VMPauseStartEvent
)
{
if
(
isolate
.
pauseEvent
is
VMPauseStartEvent
)
{
_log
(
'Isolate is paused at start.'
);
_log
(
'Isolate is paused at start.'
);
// If the isolate is paused at the start, e.g. via the --start-paused
await
resumeLeniently
();
// option, then the VM service extension is not registered yet. Wait for
// it to be registered.
await
enableIsolateStreams
();
final
Future
<
String
>
whenServiceExtensionReady
=
waitForServiceExtension
();
final
Future
<
dynamic
>
whenResumed
=
resumeLeniently
();
await
whenResumed
;
_log
(
'Waiting for service extension'
);
// We will never receive the extension event if the user does not
// register it. If that happens, show a message but continue waiting.
await
_warnIfSlow
<
String
>(
future:
whenServiceExtensionReady
,
timeout:
kUnusuallyLongTimeout
,
message:
'Flutter Driver extension is taking a long time to become available. '
'Ensure your test app (often "lib/main.dart") imports '
'"package:flutter_driver/driver_extension.dart" and '
'calls enableFlutterDriverExtension() as the first call in main().'
,
);
}
else
if
(
isolate
.
pauseEvent
is
VMPauseExitEvent
||
}
else
if
(
isolate
.
pauseEvent
is
VMPauseExitEvent
||
isolate
.
pauseEvent
is
VMPauseBreakpointEvent
||
isolate
.
pauseEvent
is
VMPauseBreakpointEvent
||
isolate
.
pauseEvent
is
VMPauseExceptionEvent
||
isolate
.
pauseEvent
is
VMPauseExceptionEvent
||
...
@@ -210,27 +217,20 @@ class VMServiceFlutterDriver extends FlutterDriver {
...
@@ -210,27 +217,20 @@ class VMServiceFlutterDriver extends FlutterDriver {
);
);
}
}
// Invoked checkHealth and try to fix delays in the registration of Service
await
enableIsolateStreams
();
// extensions
Future
<
Health
>
checkHealth
()
async
{
// We will never receive the extension event if the user does not register
try
{
// it. If that happens, show a message but continue waiting.
// At this point the service extension must be installed. Verify it.
await
_warnIfSlow
<
void
>(
return
await
driver
.
checkHealth
();
future:
waitForServiceExtension
(),
}
on
rpc
.
RpcException
catch
(
e
)
{
timeout:
kUnusuallyLongTimeout
,
if
(
e
.
code
!=
error_code
.
METHOD_NOT_FOUND
)
{
message:
'Flutter Driver extension is taking a long time to become available. '
rethrow
;
'Ensure your test app (often "lib/main.dart") imports '
}
'"package:flutter_driver/driver_extension.dart" and '
_log
(
'calls enableFlutterDriverExtension() as the first call in main().'
,
'Check Health failed, try to wait for the service extensions to be '
);
'registered.'
);
await
enableIsolateStreams
();
await
waitForServiceExtension
();
return
driver
.
checkHealth
();
}
}
final
Health
health
=
await
checkHealth
();
final
Health
health
=
await
driver
.
checkHealth
();
if
(
health
.
status
!=
HealthStatus
.
ok
)
{
if
(
health
.
status
!=
HealthStatus
.
ok
)
{
await
client
.
close
();
await
client
.
close
();
throw
DriverError
(
'Flutter application health check failed.'
);
throw
DriverError
(
'Flutter application health check failed.'
);
...
...
packages/flutter_driver/test/flutter_driver_test.dart
View file @
342c6286
...
@@ -49,6 +49,10 @@ void main() {
...
@@ -49,6 +49,10 @@ void main() {
when
(
mockClient
.
getVM
()).
thenAnswer
((
_
)
=>
Future
<
MockVM
>.
value
(
mockVM
));
when
(
mockClient
.
getVM
()).
thenAnswer
((
_
)
=>
Future
<
MockVM
>.
value
(
mockVM
));
when
(
mockVM
.
isolates
).
thenReturn
(<
VMRunnableIsolate
>[
mockIsolate
]);
when
(
mockVM
.
isolates
).
thenReturn
(<
VMRunnableIsolate
>[
mockIsolate
]);
when
(
mockIsolate
.
loadRunnable
()).
thenAnswer
((
_
)
=>
Future
<
MockIsolate
>.
value
(
mockIsolate
));
when
(
mockIsolate
.
loadRunnable
()).
thenAnswer
((
_
)
=>
Future
<
MockIsolate
>.
value
(
mockIsolate
));
when
(
mockIsolate
.
extensionRpcs
).
thenReturn
(<
String
>[]);
when
(
mockIsolate
.
onExtensionAdded
).
thenAnswer
((
Invocation
invocation
)
{
return
Stream
<
String
>.
fromIterable
(<
String
>[
'ext.flutter.driver'
]);
});
when
(
mockIsolate
.
invokeExtension
(
any
,
any
)).
thenAnswer
(
when
(
mockIsolate
.
invokeExtension
(
any
,
any
)).
thenAnswer
(
(
Invocation
invocation
)
=>
makeMockResponse
(<
String
,
dynamic
>{
'status'
:
'ok'
}));
(
Invocation
invocation
)
=>
makeMockResponse
(<
String
,
dynamic
>{
'status'
:
'ok'
}));
vmServiceConnectFunction
=
(
String
url
,
{
Map
<
String
,
dynamic
>
headers
})
{
vmServiceConnectFunction
=
(
String
url
,
{
Map
<
String
,
dynamic
>
headers
})
{
...
@@ -81,7 +85,7 @@ void main() {
...
@@ -81,7 +85,7 @@ void main() {
final
FlutterDriver
driver
=
await
FlutterDriver
.
connect
(
dartVmServiceUrl:
''
);
final
FlutterDriver
driver
=
await
FlutterDriver
.
connect
(
dartVmServiceUrl:
''
);
expect
(
driver
,
isNotNull
);
expect
(
driver
,
isNotNull
);
expectLogContains
(
'Isolate is paused at start'
);
expectLogContains
(
'Isolate is paused at start'
);
expect
(
connectionLog
,
<
String
>[
'
streamListen'
,
'onExtensionAdded'
,
'resume
'
]);
expect
(
connectionLog
,
<
String
>[
'
resume'
,
'streamListen'
,
'onExtensionAdded
'
]);
});
});
test
(
'connects to isolate paused mid-flight'
,
()
async
{
test
(
'connects to isolate paused mid-flight'
,
()
async
{
...
@@ -117,6 +121,18 @@ void main() {
...
@@ -117,6 +121,18 @@ void main() {
expectLogContains
(
'Isolate is not paused. Assuming application is ready.'
);
expectLogContains
(
'Isolate is not paused. Assuming application is ready.'
);
});
});
test
(
'connects to unpaused when onExtensionAdded does not contain the '
'driver extension'
,
()
async
{
when
(
mockIsolate
.
pauseEvent
).
thenReturn
(
MockVMResumeEvent
());
when
(
mockIsolate
.
extensionRpcs
).
thenReturn
(<
String
>[
'ext.flutter.driver'
]);
when
(
mockIsolate
.
onExtensionAdded
).
thenAnswer
((
Invocation
invocation
)
{
return
const
Stream
<
String
>.
empty
();
});
final
FlutterDriver
driver
=
await
FlutterDriver
.
connect
(
dartVmServiceUrl:
''
);
expect
(
driver
,
isNotNull
);
expectLogContains
(
'Isolate is not paused. Assuming application is ready.'
);
});
test
(
'connects with headers'
,
()
async
{
test
(
'connects with headers'
,
()
async
{
Map
<
String
,
dynamic
>
actualHeaders
;
Map
<
String
,
dynamic
>
actualHeaders
;
vmServiceConnectFunction
=
(
String
url
,
{
Map
<
String
,
dynamic
>
headers
})
{
vmServiceConnectFunction
=
(
String
url
,
{
Map
<
String
,
dynamic
>
headers
})
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment