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
1bf6f023
Unverified
Commit
1bf6f023
authored
Mar 05, 2020
by
Jonah Williams
Committed by
GitHub
Mar 05, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[flutter_tools] support coverage and machine together (#51988)
parent
bbf913bc
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
57 additions
and
24 deletions
+57
-24
test.dart
packages/flutter_tools/lib/src/commands/test.dart
+5
-8
coverage_collector.dart
packages/flutter_tools/lib/src/test/coverage_collector.dart
+24
-15
event_printer.dart
packages/flutter_tools/lib/src/test/event_printer.dart
+5
-1
test_test.dart
...flutter_tools/test/commands.shard/hermetic/test_test.dart
+23
-0
No files found.
packages/flutter_tools/lib/src/commands/test.dart
View file @
1bf6f023
...
@@ -208,24 +208,21 @@ class TestCommand extends FlutterCommand {
...
@@ -208,24 +208,21 @@ class TestCommand extends FlutterCommand {
];
];
}
}
final
bool
machine
=
boolArg
(
'machine'
);
CoverageCollector
collector
;
CoverageCollector
collector
;
if
(
boolArg
(
'coverage'
)
||
boolArg
(
'merge-coverage'
))
{
if
(
boolArg
(
'coverage'
)
||
boolArg
(
'merge-coverage'
))
{
final
String
projectName
=
FlutterProject
.
current
().
manifest
.
appName
;
final
String
projectName
=
FlutterProject
.
current
().
manifest
.
appName
;
collector
=
CoverageCollector
(
collector
=
CoverageCollector
(
verbose:
!
machine
,
libraryPredicate:
(
String
libraryName
)
=>
libraryName
.
contains
(
projectName
),
libraryPredicate:
(
String
libraryName
)
=>
libraryName
.
contains
(
projectName
),
);
);
}
}
final
bool
machine
=
boolArg
(
'machine'
);
if
(
collector
!=
null
&&
machine
)
{
throwToolExit
(
"The test command doesn't support --machine and coverage together"
);
}
TestWatcher
watcher
;
TestWatcher
watcher
;
if
(
collector
!=
null
)
{
if
(
machine
)
{
watcher
=
EventPrinter
(
parent:
collector
);
}
else
if
(
collector
!=
null
)
{
watcher
=
collector
;
watcher
=
collector
;
}
else
if
(
machine
)
{
watcher
=
EventPrinter
();
}
}
Cache
.
releaseLockEarly
();
Cache
.
releaseLockEarly
();
...
...
packages/flutter_tools/lib/src/test/coverage_collector.dart
View file @
1bf6f023
...
@@ -8,7 +8,6 @@ import 'package:coverage/coverage.dart' as coverage;
...
@@ -8,7 +8,6 @@ import 'package:coverage/coverage.dart' as coverage;
import
'../base/file_system.dart'
;
import
'../base/file_system.dart'
;
import
'../base/io.dart'
;
import
'../base/io.dart'
;
import
'../base/logger.dart'
;
import
'../base/process.dart'
;
import
'../base/process.dart'
;
import
'../base/utils.dart'
;
import
'../base/utils.dart'
;
import
'../dart/package_map.dart'
;
import
'../dart/package_map.dart'
;
...
@@ -19,17 +18,29 @@ import 'watcher.dart';
...
@@ -19,17 +18,29 @@ import 'watcher.dart';
/// A class that's used to collect coverage data during tests.
/// A class that's used to collect coverage data during tests.
class
CoverageCollector
extends
TestWatcher
{
class
CoverageCollector
extends
TestWatcher
{
CoverageCollector
({
this
.
libraryPredicate
});
CoverageCollector
({
this
.
libraryPredicate
,
this
.
verbose
=
true
});
final
bool
verbose
;
Map
<
String
,
Map
<
int
,
int
>>
_globalHitmap
;
Map
<
String
,
Map
<
int
,
int
>>
_globalHitmap
;
bool
Function
(
String
)
libraryPredicate
;
bool
Function
(
String
)
libraryPredicate
;
@override
@override
Future
<
void
>
handleFinishedTest
(
ProcessEvent
event
)
async
{
Future
<
void
>
handleFinishedTest
(
ProcessEvent
event
)
async
{
globals
.
printTrac
e
(
'test
${event.childIndex}
: collecting coverage'
);
_logMessag
e
(
'test
${event.childIndex}
: collecting coverage'
);
await
collectCoverage
(
event
.
process
,
event
.
observatoryUri
);
await
collectCoverage
(
event
.
process
,
event
.
observatoryUri
);
}
}
void
_logMessage
(
String
line
,
{
bool
error
=
false
})
{
if
(!
verbose
)
{
return
;
}
if
(
error
)
{
globals
.
printError
(
line
);
}
else
{
globals
.
printTrace
(
line
);
}
}
void
_addHitmap
(
Map
<
String
,
Map
<
int
,
int
>>
hitmap
)
{
void
_addHitmap
(
Map
<
String
,
Map
<
int
,
int
>>
hitmap
)
{
if
(
_globalHitmap
==
null
)
{
if
(
_globalHitmap
==
null
)
{
_globalHitmap
=
hitmap
;
_globalHitmap
=
hitmap
;
...
@@ -46,16 +57,16 @@ class CoverageCollector extends TestWatcher {
...
@@ -46,16 +57,16 @@ class CoverageCollector extends TestWatcher {
/// The returned [Future] completes when the coverage is collected.
/// The returned [Future] completes when the coverage is collected.
Future
<
void
>
collectCoverageIsolate
(
Uri
observatoryUri
)
async
{
Future
<
void
>
collectCoverageIsolate
(
Uri
observatoryUri
)
async
{
assert
(
observatoryUri
!=
null
);
assert
(
observatoryUri
!=
null
);
print
(
'collecting coverage data from
$observatoryUri
...'
);
_logMessage
(
'collecting coverage data from
$observatoryUri
...'
);
final
Map
<
String
,
dynamic
>
data
=
await
collect
(
observatoryUri
,
libraryPredicate
);
final
Map
<
String
,
dynamic
>
data
=
await
collect
(
observatoryUri
,
libraryPredicate
);
if
(
data
==
null
)
{
if
(
data
==
null
)
{
throw
Exception
(
'Failed to collect coverage.'
);
throw
Exception
(
'Failed to collect coverage.'
);
}
}
assert
(
data
!=
null
);
assert
(
data
!=
null
);
print
(
'(
$observatoryUri
): collected coverage data; merging...'
);
_logMessage
(
'(
$observatoryUri
): collected coverage data; merging...'
);
_addHitmap
(
coverage
.
createHitmap
(
data
[
'coverage'
]
as
List
<
Map
<
String
,
dynamic
>>));
_addHitmap
(
coverage
.
createHitmap
(
data
[
'coverage'
]
as
List
<
Map
<
String
,
dynamic
>>));
print
(
'(
$observatoryUri
): done merging coverage data into global coverage map.'
);
_logMessage
(
'(
$observatoryUri
): done merging coverage data into global coverage map.'
);
}
}
/// Collects coverage for the given [Process] using the given `port`.
/// Collects coverage for the given [Process] using the given `port`.
...
@@ -68,7 +79,7 @@ class CoverageCollector extends TestWatcher {
...
@@ -68,7 +79,7 @@ class CoverageCollector extends TestWatcher {
assert
(
process
!=
null
);
assert
(
process
!=
null
);
assert
(
observatoryUri
!=
null
);
assert
(
observatoryUri
!=
null
);
final
int
pid
=
process
.
pid
;
final
int
pid
=
process
.
pid
;
globals
.
printTrac
e
(
'pid
$pid
: collecting coverage data from
$observatoryUri
...'
);
_logMessag
e
(
'pid
$pid
: collecting coverage data from
$observatoryUri
...'
);
Map
<
String
,
dynamic
>
data
;
Map
<
String
,
dynamic
>
data
;
final
Future
<
void
>
processComplete
=
process
.
exitCode
final
Future
<
void
>
processComplete
=
process
.
exitCode
...
@@ -85,9 +96,9 @@ class CoverageCollector extends TestWatcher {
...
@@ -85,9 +96,9 @@ class CoverageCollector extends TestWatcher {
await
Future
.
any
<
void
>(<
Future
<
void
>>[
processComplete
,
collectionComplete
]);
await
Future
.
any
<
void
>(<
Future
<
void
>>[
processComplete
,
collectionComplete
]);
assert
(
data
!=
null
);
assert
(
data
!=
null
);
globals
.
printTrac
e
(
'pid
$pid
(
$observatoryUri
): collected coverage data; merging...'
);
_logMessag
e
(
'pid
$pid
(
$observatoryUri
): collected coverage data; merging...'
);
_addHitmap
(
coverage
.
createHitmap
(
data
[
'coverage'
]
as
List
<
Map
<
String
,
dynamic
>>));
_addHitmap
(
coverage
.
createHitmap
(
data
[
'coverage'
]
as
List
<
Map
<
String
,
dynamic
>>));
globals
.
printTrac
e
(
'pid
$pid
(
$observatoryUri
): done merging coverage data into global coverage map.'
);
_logMessag
e
(
'pid
$pid
(
$observatoryUri
): done merging coverage data into global coverage map.'
);
}
}
/// Returns a future that will complete with the formatted coverage data
/// Returns a future that will complete with the formatted coverage data
...
@@ -116,12 +127,10 @@ class CoverageCollector extends TestWatcher {
...
@@ -116,12 +127,10 @@ class CoverageCollector extends TestWatcher {
}
}
Future
<
bool
>
collectCoverageData
(
String
coveragePath
,
{
bool
mergeCoverageData
=
false
,
Directory
coverageDirectory
})
async
{
Future
<
bool
>
collectCoverageData
(
String
coveragePath
,
{
bool
mergeCoverageData
=
false
,
Directory
coverageDirectory
})
async
{
final
Status
status
=
globals
.
logger
.
startProgress
(
'Collecting coverage information...'
,
timeout:
timeoutConfiguration
.
fastOperation
);
final
String
coverageData
=
await
finalizeCoverage
(
final
String
coverageData
=
await
finalizeCoverage
(
coverageDirectory:
coverageDirectory
,
coverageDirectory:
coverageDirectory
,
);
);
status
.
stop
();
_logMessage
(
'coverage information collection complete'
);
globals
.
printTrace
(
'coverage information collection complete'
);
if
(
coverageData
==
null
)
{
if
(
coverageData
==
null
)
{
return
false
;
return
false
;
}
}
...
@@ -129,12 +138,12 @@ class CoverageCollector extends TestWatcher {
...
@@ -129,12 +138,12 @@ class CoverageCollector extends TestWatcher {
final
File
coverageFile
=
globals
.
fs
.
file
(
coveragePath
)
final
File
coverageFile
=
globals
.
fs
.
file
(
coveragePath
)
..
createSync
(
recursive:
true
)
..
createSync
(
recursive:
true
)
..
writeAsStringSync
(
coverageData
,
flush:
true
);
..
writeAsStringSync
(
coverageData
,
flush:
true
);
globals
.
printTrac
e
(
'wrote coverage data to
$coveragePath
(size=
${coverageData.length}
)'
);
_logMessag
e
(
'wrote coverage data to
$coveragePath
(size=
${coverageData.length}
)'
);
const
String
baseCoverageData
=
'coverage/lcov.base.info'
;
const
String
baseCoverageData
=
'coverage/lcov.base.info'
;
if
(
mergeCoverageData
)
{
if
(
mergeCoverageData
)
{
if
(!
globals
.
fs
.
isFileSync
(
baseCoverageData
))
{
if
(!
globals
.
fs
.
isFileSync
(
baseCoverageData
))
{
globals
.
printError
(
'Missing "
$baseCoverageData
". Unable to merge coverage data.'
);
_logMessage
(
'Missing "
$baseCoverageData
". Unable to merge coverage data.'
,
error:
true
);
return
false
;
return
false
;
}
}
...
@@ -145,7 +154,7 @@ class CoverageCollector extends TestWatcher {
...
@@ -145,7 +154,7 @@ class CoverageCollector extends TestWatcher {
}
else
if
(
globals
.
platform
.
isMacOS
)
{
}
else
if
(
globals
.
platform
.
isMacOS
)
{
installMessage
=
'Consider running "brew install lcov".'
;
installMessage
=
'Consider running "brew install lcov".'
;
}
}
globals
.
printError
(
'Missing "lcov" tool. Unable to merge coverage data.
\n
$installMessage
'
);
_logMessage
(
'Missing "lcov" tool. Unable to merge coverage data.
\n
$installMessage
'
,
error:
true
);
return
false
;
return
false
;
}
}
...
...
packages/flutter_tools/lib/src/test/event_printer.dart
View file @
1bf6f023
...
@@ -8,14 +8,18 @@ import 'watcher.dart';
...
@@ -8,14 +8,18 @@ import 'watcher.dart';
/// Prints JSON events when running a test in --machine mode.
/// Prints JSON events when running a test in --machine mode.
class
EventPrinter
extends
TestWatcher
{
class
EventPrinter
extends
TestWatcher
{
EventPrinter
({
StringSink
out
})
:
_out
=
out
??
globals
.
stdio
.
stdout
;
EventPrinter
({
StringSink
out
,
TestWatcher
parent
})
:
_out
=
out
??
globals
.
stdio
.
stdout
,
_parent
=
parent
;
final
StringSink
_out
;
final
StringSink
_out
;
final
TestWatcher
_parent
;
@override
@override
void
handleStartedProcess
(
ProcessEvent
event
)
{
void
handleStartedProcess
(
ProcessEvent
event
)
{
_sendEvent
(
'test.startedProcess'
,
_sendEvent
(
'test.startedProcess'
,
<
String
,
dynamic
>{
'observatoryUri'
:
event
.
observatoryUri
.
toString
()});
<
String
,
dynamic
>{
'observatoryUri'
:
event
.
observatoryUri
.
toString
()});
_parent
?.
handleStartedProcess
(
event
);
}
}
void
_sendEvent
(
String
name
,
[
dynamic
params
])
{
void
_sendEvent
(
String
name
,
[
dynamic
params
])
{
...
...
packages/flutter_tools/test/commands.shard/hermetic/test_test.dart
View file @
1bf6f023
...
@@ -6,6 +6,7 @@ import 'dart:async';
...
@@ -6,6 +6,7 @@ import 'dart:async';
import
'package:args/command_runner.dart'
;
import
'package:args/command_runner.dart'
;
import
'package:file/memory.dart'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/common.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/base/file_system.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/build_info.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
import
'package:flutter_tools/src/cache.dart'
;
...
@@ -54,6 +55,28 @@ void main() {
...
@@ -54,6 +55,28 @@ void main() {
Cache:
()
=>
FakeCache
(),
Cache:
()
=>
FakeCache
(),
});
});
testUsingContext
(
'Supports coverage and machine'
,
()
async
{
final
FakePackageTest
fakePackageTest
=
FakePackageTest
();
final
TestCommand
testCommand
=
TestCommand
(
testWrapper:
fakePackageTest
);
final
CommandRunner
<
void
>
commandRunner
=
createTestCommandRunner
(
testCommand
);
expect
(()
=>
commandRunner
.
run
(
const
<
String
>[
'test'
,
'--no-pub'
,
'--machine'
,
'--coverage'
,
'--'
,
'test/fake_test.dart'
,
]),
throwsA
(
isA
<
ToolExit
>()
.
having
((
ToolExit
toolExit
)
=>
toolExit
.
message
,
'message'
,
isNull
)));
},
overrides:
<
Type
,
Generator
>{
FileSystem:
()
=>
fs
,
ProcessManager:
()
=>
FakeProcessManager
.
any
(),
Cache:
()
=>
FakeCache
(),
});
testUsingContext
(
'Pipes start-paused to package:test'
,
testUsingContext
(
'Pipes start-paused to package:test'
,
()
async
{
()
async
{
final
FakePackageTest
fakePackageTest
=
FakePackageTest
();
final
FakePackageTest
fakePackageTest
=
FakePackageTest
();
...
...
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