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
a40ab895
Unverified
Commit
a40ab895
authored
Aug 15, 2019
by
Zachary Anderson
Committed by
GitHub
Aug 15, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tool] Observatory connection error handling cleanup (#38353)
parent
f5dcbdab
Changes
6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
267 additions
and
96 deletions
+267
-96
attach.dart
packages/flutter_tools/lib/src/commands/attach.dart
+2
-0
devices.dart
packages/flutter_tools/lib/src/ios/devices.dart
+54
-53
protocol_discovery.dart
packages/flutter_tools/lib/src/protocol_discovery.dart
+2
-2
attach_test.dart
...lutter_tools/test/general.shard/commands/attach_test.dart
+49
-9
devices_test.dart
...es/flutter_tools/test/general.shard/ios/devices_test.dart
+159
-28
mocks.dart
packages/flutter_tools/test/src/mocks.dart
+1
-4
No files found.
packages/flutter_tools/lib/src/commands/attach.dart
View file @
a40ab895
...
@@ -243,6 +243,8 @@ class AttachCommand extends FlutterCommand {
...
@@ -243,6 +243,8 @@ class AttachCommand extends FlutterCommand {
// Determine ipv6 status from the scanned logs.
// Determine ipv6 status from the scanned logs.
usesIpv6
=
observatoryDiscovery
.
ipv6
;
usesIpv6
=
observatoryDiscovery
.
ipv6
;
printStatus
(
'Done.'
);
// FYI, this message is used as a sentinel in tests.
printStatus
(
'Done.'
);
// FYI, this message is used as a sentinel in tests.
}
catch
(
error
)
{
throwToolExit
(
'Failed to establish a debug connection with
${device.name}
:
$error
'
);
}
finally
{
}
finally
{
await
observatoryDiscovery
?.
cancel
();
await
observatoryDiscovery
?.
cancel
();
}
}
...
...
packages/flutter_tools/lib/src/ios/devices.dart
View file @
a40ab895
...
@@ -152,9 +152,9 @@ class IOSDevice extends Device {
...
@@ -152,9 +152,9 @@ class IOSDevice extends Device {
@override
@override
final
String
name
;
final
String
name
;
Map
<
ApplicationPackage
,
_IOS
DeviceLogReader
>
_logReaders
;
Map
<
ApplicationPackage
,
DeviceLogReader
>
_logReaders
;
_IOS
DevicePortForwarder
_portForwarder
;
DevicePortForwarder
_portForwarder
;
@override
@override
Future
<
bool
>
get
isLocalEmulator
async
=>
false
;
Future
<
bool
>
get
isLocalEmulator
async
=>
false
;
...
@@ -342,65 +342,55 @@ class IOSDevice extends Device {
...
@@ -342,65 +342,55 @@ class IOSDevice extends Device {
if
(
platformArgs
[
'trace-startup'
]
??
false
)
if
(
platformArgs
[
'trace-startup'
]
??
false
)
launchArguments
.
add
(
'--trace-startup'
);
launchArguments
.
add
(
'--trace-startup'
);
int
installationResult
=
-
1
;
final
Status
installStatus
=
logger
.
startProgress
(
Uri
localObservatoryUri
;
'Installing and launching...'
,
timeout:
timeoutConfiguration
.
slowOperation
);
final
Status
installStatus
=
logger
.
startProgress
(
'Installing and launching...'
,
timeout:
timeoutConfiguration
.
slowOperation
);
try
{
ProtocolDiscovery
observatoryDiscovery
;
if
(!
debuggingOptions
.
debuggingEnabled
)
{
if
(
debuggingOptions
.
debuggingEnabled
)
{
// If debugging is not enabled, just launch the application and continue.
// Debugging is enabled, look for the observatory server port post launch.
printTrace
(
'Debugging is not enabled'
);
printTrace
(
'Debugging is enabled, connecting to observatory'
);
installationResult
=
await
const
IOSDeploy
().
runApp
(
deviceId:
id
,
// TODO(danrubel): The Android device class does something similar to this code below.
bundlePath:
bundle
.
path
,
// The various Device subclasses should be refactored and common code moved into the superclass.
launchArguments:
launchArguments
,
observatoryDiscovery
=
ProtocolDiscovery
.
observatory
(
);
getLogReader
(
app:
package
),
}
else
{
portForwarder:
portForwarder
,
// Debugging is enabled, look for the observatory server port post launch.
hostPort:
debuggingOptions
.
observatoryPort
,
printTrace
(
'Debugging is enabled, connecting to observatory'
);
ipv6:
ipv6
,
);
// TODO(danrubel): The Android device class does something similar to this code below.
}
// The various Device subclasses should be refactored and common code moved into the superclass.
final
ProtocolDiscovery
observatoryDiscovery
=
ProtocolDiscovery
.
observatory
(
getLogReader
(
app:
package
),
portForwarder:
portForwarder
,
hostPort:
debuggingOptions
.
observatoryPort
,
ipv6:
ipv6
,
);
final
Future
<
Uri
>
forwardObservatoryUri
=
observatoryDiscovery
.
uri
;
final
Future
<
int
>
launch
=
const
IOSDeploy
().
runApp
(
final
int
installationResult
=
await
const
IOSDeploy
().
runApp
(
deviceId:
id
,
deviceId:
id
,
bundlePath:
bundle
.
path
,
bundlePath:
bundle
.
path
,
launchArguments:
launchArguments
,
launchArguments:
launchArguments
,
);
);
if
(
installationResult
!=
0
)
{
printError
(
'Could not install
${bundle.path}
on
$id
.'
);
printError
(
'Try launching Xcode and selecting "Product > Run" to fix the problem:'
);
printError
(
' open ios/Runner.xcworkspace'
);
printError
(
''
);
return
LaunchResult
.
failed
();
}
localObservatoryUri
=
await
launch
.
then
<
Uri
>((
int
result
)
async
{
if
(!
debuggingOptions
.
debuggingEnabled
)
{
installationResult
=
result
;
return
LaunchResult
.
succeeded
();
}
if
(
result
!=
0
)
{
printTrace
(
'Failed to launch the application on device.'
);
return
null
;
}
try
{
printTrace
(
'Application launched on the device. Waiting for observatory port.'
);
printTrace
(
'Application launched on the device. Waiting for observatory port.'
);
return
await
forwardObservatoryUri
;
final
Uri
localUri
=
await
observatoryDiscovery
.
uri
;
}).
whenComplete
(()
{
return
LaunchResult
.
succeeded
(
observatoryUri:
localUri
);
observatoryDiscovery
.
cancel
();
}
catch
(
error
)
{
});
printError
(
'Failed to establish a debug connection with
$id
:
$error
'
);
}
return
LaunchResult
.
failed
();
installStatus
.
stop
();
}
finally
{
await
observatoryDiscovery
?.
cancel
();
if
(
installationResult
!=
0
)
{
}
printError
(
'Could not install
${bundle.path}
on
$id
.'
);
}
finally
{
printError
(
'Try launching Xcode and selecting "Product > Run" to fix the problem:'
);
installStatus
.
stop
();
printError
(
' open ios/Runner.xcworkspace'
);
printError
(
''
);
return
LaunchResult
.
failed
();
}
}
return
LaunchResult
.
succeeded
(
observatoryUri:
localObservatoryUri
);
}
}
@override
@override
...
@@ -417,13 +407,24 @@ class IOSDevice extends Device {
...
@@ -417,13 +407,24 @@ class IOSDevice extends Device {
@override
@override
DeviceLogReader
getLogReader
({
ApplicationPackage
app
})
{
DeviceLogReader
getLogReader
({
ApplicationPackage
app
})
{
_logReaders
??=
<
ApplicationPackage
,
_IOS
DeviceLogReader
>{};
_logReaders
??=
<
ApplicationPackage
,
DeviceLogReader
>{};
return
_logReaders
.
putIfAbsent
(
app
,
()
=>
_IOSDeviceLogReader
(
this
,
app
));
return
_logReaders
.
putIfAbsent
(
app
,
()
=>
_IOSDeviceLogReader
(
this
,
app
));
}
}
@visibleForTesting
void
setLogReader
(
ApplicationPackage
app
,
DeviceLogReader
logReader
)
{
_logReaders
??=
<
ApplicationPackage
,
DeviceLogReader
>{};
_logReaders
[
app
]
=
logReader
;
}
@override
@override
DevicePortForwarder
get
portForwarder
=>
_portForwarder
??=
_IOSDevicePortForwarder
(
this
);
DevicePortForwarder
get
portForwarder
=>
_portForwarder
??=
_IOSDevicePortForwarder
(
this
);
@visibleForTesting
set
portForwarder
(
DevicePortForwarder
forwarder
)
{
_portForwarder
=
forwarder
;
}
@override
@override
void
clearLogs
()
{
}
void
clearLogs
()
{
}
...
...
packages/flutter_tools/lib/src/protocol_discovery.dart
View file @
a40ab895
...
@@ -65,9 +65,9 @@ class ProtocolDiscovery {
...
@@ -65,9 +65,9 @@ class ProtocolDiscovery {
if
(
match
!=
null
)
{
if
(
match
!=
null
)
{
try
{
try
{
uri
=
Uri
.
parse
(
match
[
1
]);
uri
=
Uri
.
parse
(
match
[
1
]);
}
catch
(
error
)
{
}
catch
(
error
,
stackTrace
)
{
_stopScrapingLogs
();
_stopScrapingLogs
();
_completer
.
completeError
(
error
);
_completer
.
completeError
(
error
,
stackTrace
);
}
}
}
}
...
...
packages/flutter_tools/test/general.shard/commands/attach_test.dart
View file @
a40ab895
...
@@ -52,15 +52,6 @@ void main() {
...
@@ -52,15 +52,6 @@ void main() {
mockLogReader
=
MockDeviceLogReader
();
mockLogReader
=
MockDeviceLogReader
();
portForwarder
=
MockPortForwarder
();
portForwarder
=
MockPortForwarder
();
device
=
MockAndroidDevice
();
device
=
MockAndroidDevice
();
when
(
device
.
getLogReader
()).
thenAnswer
((
_
)
{
// Now that the reader is used, start writing messages to it.
Timer
.
run
(()
{
mockLogReader
.
addLine
(
'Foo'
);
mockLogReader
.
addLine
(
'Observatory listening on http://127.0.0.1:
$devicePort
'
);
});
return
mockLogReader
;
});
when
(
device
.
portForwarder
)
when
(
device
.
portForwarder
)
.
thenReturn
(
portForwarder
);
.
thenReturn
(
portForwarder
);
when
(
portForwarder
.
forward
(
devicePort
,
hostPort:
anyNamed
(
'hostPort'
)))
when
(
portForwarder
.
forward
(
devicePort
,
hostPort:
anyNamed
(
'hostPort'
)))
...
@@ -82,6 +73,14 @@ void main() {
...
@@ -82,6 +73,14 @@ void main() {
});
});
testUsingContext
(
'finds observatory port and forwards'
,
()
async
{
testUsingContext
(
'finds observatory port and forwards'
,
()
async
{
when
(
device
.
getLogReader
()).
thenAnswer
((
_
)
{
// Now that the reader is used, start writing messages to it.
Timer
.
run
(()
{
mockLogReader
.
addLine
(
'Foo'
);
mockLogReader
.
addLine
(
'Observatory listening on http://127.0.0.1:
$devicePort
'
);
});
return
mockLogReader
;
});
testDeviceManager
.
addDevice
(
device
);
testDeviceManager
.
addDevice
(
device
);
final
Completer
<
void
>
completer
=
Completer
<
void
>();
final
Completer
<
void
>
completer
=
Completer
<
void
>();
final
StreamSubscription
<
String
>
loggerSubscription
=
logger
.
stream
.
listen
((
String
message
)
{
final
StreamSubscription
<
String
>
loggerSubscription
=
logger
.
stream
.
listen
((
String
message
)
{
...
@@ -102,7 +101,32 @@ void main() {
...
@@ -102,7 +101,32 @@ void main() {
Logger:
()
=>
logger
,
Logger:
()
=>
logger
,
});
});
testUsingContext
(
'Fails with tool exit on bad Observatory uri'
,
()
async
{
when
(
device
.
getLogReader
()).
thenAnswer
((
_
)
{
// Now that the reader is used, start writing messages to it.
Timer
.
run
(()
{
mockLogReader
.
addLine
(
'Foo'
);
mockLogReader
.
addLine
(
'Observatory listening on http:/:/127.0.0.1:
$devicePort
'
);
});
return
mockLogReader
;
});
testDeviceManager
.
addDevice
(
device
);
expect
(
createTestCommandRunner
(
AttachCommand
()).
run
(<
String
>[
'attach'
]),
throwsA
(
isA
<
ToolExit
>()));
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
testFileSystem
,
Logger:
()
=>
logger
,
});
testUsingContext
(
'accepts filesystem parameters'
,
()
async
{
testUsingContext
(
'accepts filesystem parameters'
,
()
async
{
when
(
device
.
getLogReader
()).
thenAnswer
((
_
)
{
// Now that the reader is used, start writing messages to it.
Timer
.
run
(()
{
mockLogReader
.
addLine
(
'Foo'
);
mockLogReader
.
addLine
(
'Observatory listening on http://127.0.0.1:
$devicePort
'
);
});
return
mockLogReader
;
});
testDeviceManager
.
addDevice
(
device
);
testDeviceManager
.
addDevice
(
device
);
const
String
filesystemScheme
=
'foo'
;
const
String
filesystemScheme
=
'foo'
;
...
@@ -175,6 +199,14 @@ void main() {
...
@@ -175,6 +199,14 @@ void main() {
});
});
testUsingContext
(
'exits when ipv6 is specified and debug-port is not'
,
()
async
{
testUsingContext
(
'exits when ipv6 is specified and debug-port is not'
,
()
async
{
when
(
device
.
getLogReader
()).
thenAnswer
((
_
)
{
// Now that the reader is used, start writing messages to it.
Timer
.
run
(()
{
mockLogReader
.
addLine
(
'Foo'
);
mockLogReader
.
addLine
(
'Observatory listening on http://127.0.0.1:
$devicePort
'
);
});
return
mockLogReader
;
});
testDeviceManager
.
addDevice
(
device
);
testDeviceManager
.
addDevice
(
device
);
final
AttachCommand
command
=
AttachCommand
();
final
AttachCommand
command
=
AttachCommand
();
...
@@ -190,6 +222,14 @@ void main() {
...
@@ -190,6 +222,14 @@ void main() {
},);
},);
testUsingContext
(
'exits when observatory-port is specified and debug-port is not'
,
()
async
{
testUsingContext
(
'exits when observatory-port is specified and debug-port is not'
,
()
async
{
when
(
device
.
getLogReader
()).
thenAnswer
((
_
)
{
// Now that the reader is used, start writing messages to it.
Timer
.
run
(()
{
mockLogReader
.
addLine
(
'Foo'
);
mockLogReader
.
addLine
(
'Observatory listening on http://127.0.0.1:
$devicePort
'
);
});
return
mockLogReader
;
});
testDeviceManager
.
addDevice
(
device
);
testDeviceManager
.
addDevice
(
device
);
final
AttachCommand
command
=
AttachCommand
();
final
AttachCommand
command
=
AttachCommand
();
...
...
packages/flutter_tools/test/general.shard/ios/devices_test.dart
View file @
a40ab895
This diff is collapsed.
Click to expand it.
packages/flutter_tools/test/src/mocks.dart
View file @
a40ab895
...
@@ -153,7 +153,7 @@ ro.build.version.codename=REL
...
@@ -153,7 +153,7 @@ ro.build.version.codename=REL
typedef
ProcessFactory
=
Process
Function
(
List
<
String
>
command
);
typedef
ProcessFactory
=
Process
Function
(
List
<
String
>
command
);
/// A ProcessManager that starts Processes by delegating to a ProcessFactory.
/// A ProcessManager that starts Processes by delegating to a ProcessFactory.
class
MockProcessManager
implements
ProcessManager
{
class
MockProcessManager
extends
Mock
implements
ProcessManager
{
ProcessFactory
processFactory
=
(
List
<
String
>
commands
)
=>
MockProcess
();
ProcessFactory
processFactory
=
(
List
<
String
>
commands
)
=>
MockProcess
();
bool
canRunSucceeds
=
true
;
bool
canRunSucceeds
=
true
;
bool
runSucceeds
=
true
;
bool
runSucceeds
=
true
;
...
@@ -180,9 +180,6 @@ class MockProcessManager implements ProcessManager {
...
@@ -180,9 +180,6 @@ class MockProcessManager implements ProcessManager {
commands
=
command
;
commands
=
command
;
return
Future
<
Process
>.
value
(
processFactory
(
command
));
return
Future
<
Process
>.
value
(
processFactory
(
command
));
}
}
@override
dynamic
noSuchMethod
(
Invocation
invocation
)
=>
null
;
}
}
/// A process that exits successfully with no output and ignores all input.
/// A process that exits successfully with no output and ignores all input.
...
...
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