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
8d3bc184
Unverified
Commit
8d3bc184
authored
Apr 26, 2021
by
Jenn Magder
Committed by
GitHub
Apr 26, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate analyze_size to null safety (#81002)
parent
b8833afc
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
125 additions
and
82 deletions
+125
-82
analyze_size.dart
packages/flutter_tools/lib/src/base/analyze_size.dart
+82
-70
analyze_size_test.dart
...tter_tools/test/general.shard/base/analyze_size_test.dart
+41
-11
analyze_size_test.dart
...utter_tools/test/integration.shard/analyze_size_test.dart
+2
-1
No files found.
packages/flutter_tools/lib/src/base/analyze_size.dart
View file @
8d3bc184
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import
'package:archive/archive.dart'
;
import
'package:archive/archive_io.dart'
;
import
'package:meta/meta.dart'
;
...
...
@@ -11,6 +9,7 @@ import 'package:vm_snapshot_analysis/treemap.dart';
import
'../convert.dart'
;
import
'../reporting/reporting.dart'
;
import
'common.dart'
;
import
'file_system.dart'
;
import
'logger.dart'
;
import
'terminal.dart'
;
...
...
@@ -18,10 +17,9 @@ import 'terminal.dart';
/// A class to analyze APK and AOT snapshot and generate a breakdown of the data.
class
SizeAnalyzer
{
SizeAnalyzer
({
@required
FileSystem
fileSystem
,
@required
Logger
logger
,
// TODO(jonahwilliams): migrate to required once this has rolled into google3.
Usage
flutterUsage
,
required
FileSystem
fileSystem
,
required
Logger
logger
,
required
Usage
flutterUsage
,
Pattern
appFilenamePattern
=
'libapp.so'
,
})
:
_flutterUsage
=
flutterUsage
,
_fileSystem
=
fileSystem
,
...
...
@@ -32,7 +30,7 @@ class SizeAnalyzer {
final
Logger
_logger
;
final
Pattern
_appFilenamePattern
;
final
Usage
_flutterUsage
;
String
_appFilename
;
String
?
_appFilename
;
static
const
String
aotSnapshotFileName
=
'aot-snapshot.json'
;
static
const
int
tableWidth
=
80
;
...
...
@@ -40,12 +38,12 @@ class SizeAnalyzer {
static
const
int
_kZipSizeMaxDepth
=
1
;
/// Analyze the [aotSnapshot] in an uncompressed output directory.
Future
<
Map
<
String
,
dynamic
>>
analyzeAotSnapshot
({
@
required
Directory
outputDirectory
,
@
required
File
aotSnapshot
,
@
required
File
precompilerTrace
,
@
required
String
type
,
String
excludePath
,
Future
<
Map
<
String
,
Object
?
>>
analyzeAotSnapshot
({
required
Directory
outputDirectory
,
required
File
aotSnapshot
,
required
File
precompilerTrace
,
required
String
type
,
String
?
excludePath
,
})
async
{
_logger
.
printStatus
(
'▒'
*
tableWidth
);
_logger
.
printStatus
(
'━'
*
tableWidth
);
...
...
@@ -56,10 +54,12 @@ class SizeAnalyzer {
);
// Convert an AOT snapshot file into a map.
final
Map
<
String
,
dynamic
>
processedAotSnapshotJson
=
treemapFromJson
(
json
.
decode
(
aotSnapshot
.
readAsStringSync
()),
);
final
_SymbolNode
aotSnapshotJsonRoot
=
_parseAotSnapshot
(
processedAotSnapshotJson
);
final
Object
?
decodedAotSnapshot
=
json
.
decode
(
aotSnapshot
.
readAsStringSync
());
if
(
decodedAotSnapshot
==
null
)
{
throwToolExit
(
'AOT snapshot is invalid for analysis'
);
}
final
Map
<
String
,
Object
?>
processedAotSnapshotJson
=
treemapFromJson
(
decodedAotSnapshot
);
final
_SymbolNode
?
aotSnapshotJsonRoot
=
_parseAotSnapshot
(
processedAotSnapshotJson
);
for
(
final
_SymbolNode
firstLevelPath
in
aotAnalysisJson
.
children
)
{
_printEntitySize
(
...
...
@@ -68,14 +68,14 @@ class SizeAnalyzer {
level:
1
,
);
// Print the expansion of lib directory to show more info for `appFilename`.
if
(
firstLevelPath
.
name
==
_fileSystem
.
path
.
basename
(
outputDirectory
.
path
))
{
if
(
firstLevelPath
.
name
==
_fileSystem
.
path
.
basename
(
outputDirectory
.
path
)
&&
aotSnapshotJsonRoot
!=
null
)
{
_printLibChildrenPaths
(
firstLevelPath
,
''
,
aotSnapshotJsonRoot
,
_kAotSizeMaxDepth
,
0
);
}
}
_logger
.
printStatus
(
'▒'
*
tableWidth
);
Map
<
String
,
dynamic
>
apkAnalysisJson
=
aotAnalysisJson
.
toJson
();
Map
<
String
,
Object
?
>
apkAnalysisJson
=
aotAnalysisJson
.
toJson
();
apkAnalysisJson
[
'type'
]
=
type
;
// one of apk, aab, ios, macos, windows, or linux.
...
...
@@ -83,7 +83,7 @@ class SizeAnalyzer {
apkAnalysisJson:
apkAnalysisJson
,
path:
_locatedAotFilePath
,
aotSnapshotJson:
processedAotSnapshotJson
,
precompilerTrace:
json
.
decode
(
precompilerTrace
.
readAsStringSync
())
as
Map
<
String
,
Object
>
,
precompilerTrace:
json
.
decode
(
precompilerTrace
.
readAsStringSync
())
as
Map
<
String
,
Object
?>?
??
<
String
,
Object
?>{}
,
);
assert
(
_appFilename
!=
null
);
...
...
@@ -97,11 +97,11 @@ class SizeAnalyzer {
///
/// [kind] must be one of 'apk' or 'aab'.
/// The [aotSnapshot] can be either instruction sizes snapshot or a v8 snapshot.
Future
<
Map
<
String
,
dynamic
>>
analyzeZipSizeAndAotSnapshot
({
@
required
File
zipFile
,
@
required
File
aotSnapshot
,
@
required
File
precompilerTrace
,
@
required
String
kind
,
Future
<
Map
<
String
,
Object
?
>>
analyzeZipSizeAndAotSnapshot
({
required
File
zipFile
,
required
File
aotSnapshot
,
required
File
precompilerTrace
,
required
String
kind
,
})
async
{
assert
(
kind
==
'apk'
||
kind
==
'aab'
);
_logger
.
printStatus
(
'▒'
*
tableWidth
);
...
...
@@ -116,16 +116,20 @@ class SizeAnalyzer {
final
_SymbolNode
apkAnalysisRoot
=
_parseUnzipFile
(
zipFile
);
// Convert an AOT snapshot file into a map.
final
Map
<
String
,
dynamic
>
processedAotSnapshotJson
=
treemapFromJson
(
json
.
decode
(
aotSnapshot
.
readAsStringSync
()),
);
final
_SymbolNode
aotSnapshotJsonRoot
=
_parseAotSnapshot
(
processedAotSnapshotJson
);
for
(
final
_SymbolNode
firstLevelPath
in
apkAnalysisRoot
.
children
)
{
_printLibChildrenPaths
(
firstLevelPath
,
''
,
aotSnapshotJsonRoot
,
_kZipSizeMaxDepth
,
0
);
final
Object
?
decodedAotSnapshot
=
json
.
decode
(
aotSnapshot
.
readAsStringSync
());
if
(
decodedAotSnapshot
==
null
)
{
throwToolExit
(
'AOT snapshot is invalid for analysis'
);
}
final
Map
<
String
,
Object
?>
processedAotSnapshotJson
=
treemapFromJson
(
decodedAotSnapshot
);
final
_SymbolNode
?
aotSnapshotJsonRoot
=
_parseAotSnapshot
(
processedAotSnapshotJson
);
if
(
aotSnapshotJsonRoot
!=
null
)
{
for
(
final
_SymbolNode
firstLevelPath
in
apkAnalysisRoot
.
children
)
{
_printLibChildrenPaths
(
firstLevelPath
,
''
,
aotSnapshotJsonRoot
,
_kZipSizeMaxDepth
,
0
);
}
}
_logger
.
printStatus
(
'▒'
*
tableWidth
);
Map
<
String
,
dynamic
>
apkAnalysisJson
=
apkAnalysisRoot
.
toJson
();
Map
<
String
,
Object
?
>
apkAnalysisJson
=
apkAnalysisRoot
.
toJson
();
apkAnalysisJson
[
'type'
]
=
kind
;
...
...
@@ -134,7 +138,7 @@ class SizeAnalyzer {
apkAnalysisJson:
apkAnalysisJson
,
path:
_locatedAotFilePath
,
aotSnapshotJson:
processedAotSnapshotJson
,
precompilerTrace:
json
.
decode
(
precompilerTrace
.
readAsStringSync
())
as
Map
<
String
,
Object
>
,
precompilerTrace:
json
.
decode
(
precompilerTrace
.
readAsStringSync
())
as
Map
<
String
,
Object
?>?
??
<
String
,
Object
?>{}
,
);
CodeSizeEvent
(
kind
,
flutterUsage:
_flutterUsage
).
send
();
return
apkAnalysisJson
;
...
...
@@ -145,12 +149,15 @@ class SizeAnalyzer {
final
Map
<
List
<
String
>,
int
>
pathsToSize
=
<
List
<
String
>,
int
>{};
for
(
final
ArchiveFile
archiveFile
in
archive
.
files
)
{
pathsToSize
[
_fileSystem
.
path
.
split
(
archiveFile
.
name
)]
=
archiveFile
.
rawContent
.
length
;
final
InputStream
?
rawContent
=
archiveFile
.
rawContent
;
if
(
rawContent
!=
null
)
{
pathsToSize
[
_fileSystem
.
path
.
split
(
archiveFile
.
name
)]
=
rawContent
.
length
;
}
}
return
_buildSymbolTree
(
pathsToSize
);
}
_SymbolNode
_parseDirectory
(
Directory
directory
,
String
relativeTo
,
String
excludePath
)
{
_SymbolNode
_parseDirectory
(
Directory
directory
,
String
relativeTo
,
String
?
excludePath
)
{
final
Map
<
List
<
String
>,
int
>
pathsToSize
=
<
List
<
String
>,
int
>{};
for
(
final
File
file
in
directory
.
listSync
(
recursive:
true
).
whereType
<
File
>())
{
if
(
excludePath
!=
null
&&
file
.
uri
.
pathSegments
.
contains
(
excludePath
))
{
...
...
@@ -163,9 +170,9 @@ class SizeAnalyzer {
return
_buildSymbolTree
(
pathsToSize
);
}
List
<
String
>
_locatedAotFilePath
;
List
<
String
>
_locatedAotFilePath
=
<
String
>[]
;
List
<
String
>
_buildNodeName
(
_SymbolNode
start
,
_SymbolNode
parent
)
{
List
<
String
>
_buildNodeName
(
_SymbolNode
start
,
_SymbolNode
?
parent
)
{
final
List
<
String
>
results
=
<
String
>[
start
.
name
];
while
(
parent
!=
null
&&
parent
.
name
!=
'Root'
)
{
results
.
insert
(
0
,
parent
.
name
);
...
...
@@ -180,7 +187,7 @@ class SizeAnalyzer {
for
(
final
List
<
String
>
paths
in
pathsToSize
.
keys
)
{
for
(
final
String
path
in
paths
)
{
_SymbolNode
childWithPathAsName
=
currentNode
.
childByName
(
path
);
_SymbolNode
?
childWithPathAsName
=
currentNode
.
childByName
(
path
);
if
(
childWithPathAsName
==
null
)
{
childWithPathAsName
=
_SymbolNode
(
path
);
...
...
@@ -193,7 +200,7 @@ class SizeAnalyzer {
}
currentNode
.
addChild
(
childWithPathAsName
);
}
childWithPathAsName
.
addSize
(
pathsToSize
[
paths
]);
childWithPathAsName
.
addSize
(
pathsToSize
[
paths
]
??
0
);
currentNode
=
childWithPathAsName
;
}
currentNode
=
rootNode
;
...
...
@@ -240,7 +247,7 @@ class SizeAnalyzer {
/// Go through the AOT gen snapshot size JSON and print out a collapsed summary
/// for the first package level.
void
_printAotSnapshotSummary
(
_SymbolNode
aotSnapshotRoot
,
{
int
maxDirectoriesShown
=
20
,
@
required
int
level
})
{
void
_printAotSnapshotSummary
(
_SymbolNode
aotSnapshotRoot
,
{
int
maxDirectoriesShown
=
20
,
required
int
level
})
{
_printEntitySize
(
'Dart AOT symbols accounted decompressed size'
,
byteSize:
aotSnapshotRoot
.
byteSize
,
...
...
@@ -273,19 +280,19 @@ class SizeAnalyzer {
}
/// Adds breakdown of aot snapshot data as the children of the node at the given path.
Map
<
String
,
dynamic
>
_addAotSnapshotDataToAnalysis
({
@required
Map
<
String
,
dynamic
>
apkAnalysisJson
,
@
required
List
<
String
>
path
,
@required
Map
<
String
,
dynamic
>
aotSnapshotJson
,
@required
Map
<
String
,
dynamic
>
precompilerTrace
,
Map
<
String
,
Object
?
>
_addAotSnapshotDataToAnalysis
({
required
Map
<
String
,
Object
?
>
apkAnalysisJson
,
required
List
<
String
>
path
,
required
Map
<
String
,
Object
?
>
aotSnapshotJson
,
required
Map
<
String
,
Object
?
>
precompilerTrace
,
})
{
Map
<
String
,
dynamic
>
currentLevel
=
apkAnalysisJson
;
Map
<
String
,
Object
?
>
currentLevel
=
apkAnalysisJson
;
currentLevel
[
'precompiler-trace'
]
=
precompilerTrace
;
while
(
path
.
isNotEmpty
)
{
final
List
<
Map
<
String
,
dynamic
>>
children
=
currentLevel
[
'children'
]
as
List
<
Map
<
String
,
dynamic
>>
;
final
Map
<
String
,
dynamic
>
childWithPathAsName
=
children
.
firstWhere
(
(
Map
<
String
,
dynamic
>
child
)
=>
child
[
'n'
]
as
String
==
path
.
first
,
);
final
List
<
Map
<
String
,
Object
?>>?
children
=
currentLevel
[
'children'
]
as
List
<
Map
<
String
,
Object
?>>?
;
final
Map
<
String
,
Object
?>
childWithPathAsName
=
children
?
.
firstWhere
(
(
Map
<
String
,
Object
?>
child
)
=>
(
child
[
'n'
]
as
String
?)
==
path
.
first
,
)
??
<
String
,
Object
?>{}
;
path
.
removeAt
(
0
);
currentLevel
=
childWithPathAsName
;
}
...
...
@@ -298,8 +305,8 @@ class SizeAnalyzer {
/// Print an entity's name with its size on the same line.
void
_printEntitySize
(
String
entityName
,
{
@
required
int
byteSize
,
@
required
int
level
,
required
int
byteSize
,
required
int
level
,
bool
showColor
=
true
,
bool
emphasis
=
false
,
})
{
...
...
@@ -354,13 +361,13 @@ class SizeAnalyzer {
}
}
_SymbolNode
_parseAotSnapshot
(
Map
<
String
,
dynamic
>
aotSnapshotJson
)
{
_SymbolNode
?
_parseAotSnapshot
(
Map
<
String
,
Object
?
>
aotSnapshotJson
)
{
final
bool
isLeafNode
=
aotSnapshotJson
[
'children'
]
==
null
;
if
(!
isLeafNode
)
{
return
_buildNodeWithChildren
(
aotSnapshotJson
);
}
else
{
// TODO(peterdjlee): Investigate why there are leaf nodes with size of null.
final
int
byteSize
=
aotSnapshotJson
[
'value'
]
as
int
;
final
int
?
byteSize
=
aotSnapshotJson
[
'value'
]
as
int
?
;
if
(
byteSize
==
null
)
{
return
null
;
}
...
...
@@ -369,11 +376,11 @@ class SizeAnalyzer {
}
_SymbolNode
_buildNode
(
Map
<
String
,
dynamic
>
aotSnapshotJson
,
Map
<
String
,
Object
?
>
aotSnapshotJson
,
int
byteSize
,
{
List
<
_SymbolNode
>
children
=
const
<
_SymbolNode
>[],
})
{
final
String
name
=
aotSnapshotJson
[
'n'
]
as
String
;
final
String
name
=
aotSnapshotJson
[
'n'
]
!
as
String
;
final
Map
<
String
,
_SymbolNode
>
childrenMap
=
<
String
,
_SymbolNode
>{};
for
(
final
_SymbolNode
child
in
children
)
{
...
...
@@ -388,16 +395,21 @@ class SizeAnalyzer {
/// Builds a node by recursively building all of its children first
/// in order to calculate the sum of its children's sizes.
_SymbolNode
_buildNodeWithChildren
(
Map
<
String
,
dynamic
>
aotSnapshotJson
)
{
final
List
<
dynamic
>
rawChildren
=
aotSnapshotJson
[
'children'
]
as
List
<
dynamic
>
;
_SymbolNode
?
_buildNodeWithChildren
(
Map
<
String
,
Object
?
>
aotSnapshotJson
)
{
final
List
<
Object
?>
rawChildren
=
aotSnapshotJson
[
'children'
]
as
List
<
Object
?>?
??
<
Object
?>[]
;
final
List
<
_SymbolNode
>
symbolNodeChildren
=
<
_SymbolNode
>[];
int
totalByteSize
=
0
;
// Given a child, build its subtree.
for
(
final
dynamic
child
in
rawChildren
)
{
final
_SymbolNode
childTreemapNode
=
_parseAotSnapshot
(
child
as
Map
<
String
,
dynamic
>);
symbolNodeChildren
.
add
(
childTreemapNode
);
totalByteSize
+=
childTreemapNode
.
byteSize
;
for
(
final
Object
?
child
in
rawChildren
)
{
if
(
child
==
null
)
{
continue
;
}
final
_SymbolNode
?
childTreemapNode
=
_parseAotSnapshot
(
child
as
Map
<
String
,
Object
?>);
if
(
childTreemapNode
!=
null
)
{
symbolNodeChildren
.
add
(
childTreemapNode
);
totalByteSize
+=
childTreemapNode
.
byteSize
;
}
}
// If none of the children matched the diff tree type
...
...
@@ -430,13 +442,13 @@ class _SymbolNode {
byteSize
+=
sizeToBeAdded
;
}
_SymbolNode
get
parent
=>
_parent
;
_SymbolNode
_parent
;
_SymbolNode
?
get
parent
=>
_parent
;
_SymbolNode
?
_parent
;
Iterable
<
_SymbolNode
>
get
children
=>
_children
.
values
;
final
Map
<
String
,
_SymbolNode
>
_children
;
_SymbolNode
childByName
(
String
name
)
=>
_children
[
name
];
_SymbolNode
?
childByName
(
String
name
)
=>
_children
[
name
];
_SymbolNode
addChild
(
_SymbolNode
child
)
{
assert
(
child
.
parent
==
null
);
...
...
@@ -452,12 +464,12 @@ class _SymbolNode {
children
.
forEach
(
addChild
);
}
Map
<
String
,
dynamic
>
toJson
()
{
final
Map
<
String
,
dynamic
>
json
=
<
String
,
dynamic
>{
Map
<
String
,
Object
?
>
toJson
()
{
final
Map
<
String
,
Object
?>
json
=
<
String
,
Object
?
>{
'n'
:
name
,
'value'
:
byteSize
};
final
List
<
Map
<
String
,
dynamic
>>
childrenAsJson
=
<
Map
<
String
,
dynamic
>>[];
final
List
<
Map
<
String
,
Object
?>>
childrenAsJson
=
<
Map
<
String
,
Object
?
>>[];
for
(
final
_SymbolNode
child
in
children
)
{
childrenAsJson
.
add
(
child
.
toJson
());
}
...
...
@@ -470,7 +482,7 @@ class _SymbolNode {
/// Matches `pattern` against the entirety of `string`.
@visibleForTesting
Match
matchesPattern
(
String
string
,
{
@
required
Pattern
pattern
})
{
final
Match
match
=
pattern
.
matchAsPrefix
(
string
);
Match
?
matchesPattern
(
String
string
,
{
required
Pattern
pattern
})
{
final
Match
?
match
=
pattern
.
matchAsPrefix
(
string
);
return
(
match
!=
null
&&
match
.
end
==
string
.
length
)
?
match
:
null
;
}
packages/flutter_tools/test/general.shard/base/analyze_size_test.dart
View file @
8d3bc184
...
...
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// @dart = 2.8
import
'package:archive/archive.dart'
;
import
'package:file/memory.dart'
;
import
'package:flutter_tools/src/base/analyze_size.dart'
;
...
...
@@ -43,15 +41,15 @@ const String aotSizeOutput = '''
'''
;
void
main
(
)
{
MemoryFileSystem
fileSystem
;
BufferLogger
logger
;
late
MemoryFileSystem
fileSystem
;
late
BufferLogger
logger
;
setUp
(()
{
fileSystem
=
MemoryFileSystem
.
test
();
logger
=
BufferLogger
.
test
();
});
test
(
'matchesPattern matches only entire strings'
,
()
{
test
WithoutContext
(
'matchesPattern matches only entire strings'
,
()
{
expect
(
matchesPattern
(
''
,
pattern:
''
),
isNotNull
);
expect
(
matchesPattern
(
''
,
pattern:
'foo'
),
null
);
expect
(
matchesPattern
(
'foo'
,
pattern:
''
),
null
);
...
...
@@ -62,7 +60,7 @@ void main() {
expect
(
matchesPattern
(
'foobar'
,
pattern:
RegExp
(
r'.*b'
)),
null
);
});
test
(
'builds APK analysis correctly'
,
()
async
{
test
WithoutContext
(
'builds APK analysis correctly'
,
()
async
{
final
SizeAnalyzer
sizeAnalyzer
=
SizeAnalyzer
(
fileSystem:
fileSystem
,
logger:
logger
,
...
...
@@ -78,7 +76,7 @@ void main() {
..
addFile
(
ArchiveFile
(
'lib/arm64-v8a/libflutter.so'
,
50
,
List
<
int
>.
filled
(
50
,
0
)));
final
File
apk
=
fileSystem
.
file
(
'test.apk'
)
..
writeAsBytesSync
(
ZipEncoder
().
encode
(
archive
));
..
writeAsBytesSync
(
ZipEncoder
().
encode
(
archive
)
!
);
final
File
aotSizeJson
=
fileSystem
.
file
(
'test.json'
)
..
createSync
()
..
writeAsStringSync
(
aotSizeOutput
);
...
...
@@ -139,7 +137,7 @@ void main() {
expect
(
result
[
'precompiler-trace'
],
<
String
,
Object
>{});
});
test
(
'outputs summary to command line correctly'
,
()
async
{
test
WithoutContext
(
'outputs summary to command line correctly'
,
()
async
{
final
SizeAnalyzer
sizeAnalyzer
=
SizeAnalyzer
(
fileSystem:
fileSystem
,
logger:
logger
,
...
...
@@ -155,7 +153,7 @@ void main() {
..
addFile
(
ArchiveFile
(
'lib/arm64-v8a/libflutter.so'
,
50
,
List
<
int
>.
filled
(
50
,
0
)));
final
File
apk
=
fileSystem
.
file
(
'test.apk'
)
..
writeAsBytesSync
(
ZipEncoder
().
encode
(
archive
));
..
writeAsBytesSync
(
ZipEncoder
().
encode
(
archive
)
!
);
final
File
aotSizeJson
=
fileSystem
.
file
(
'test.json'
)
..
writeAsStringSync
(
aotSizeOutput
);
final
File
precompilerTrace
=
fileSystem
.
file
(
'trace.json'
)
...
...
@@ -181,7 +179,7 @@ void main() {
);
});
test
(
'can analyze contents of output directory'
,
()
async
{
test
WithoutContext
(
'can analyze contents of output directory'
,
()
async
{
final
SizeAnalyzer
sizeAnalyzer
=
SizeAnalyzer
(
fileSystem:
fileSystem
,
logger:
logger
,
...
...
@@ -202,7 +200,7 @@ void main() {
final
File
precompilerTrace
=
fileSystem
.
file
(
'trace.json'
)
..
writeAsStringSync
(
'{}'
);
final
Map
<
String
,
Object
>
result
=
await
sizeAnalyzer
.
analyzeAotSnapshot
(
final
Map
<
String
,
Object
?
>
result
=
await
sizeAnalyzer
.
analyzeAotSnapshot
(
outputDirectory:
outputDirectory
,
aotSnapshot:
aotSizeJson
,
precompilerTrace:
precompilerTrace
,
...
...
@@ -223,4 +221,36 @@ void main() {
expect
(
result
[
'type'
],
'linux'
);
expect
(
result
[
'precompiler-trace'
],
<
String
,
Object
>{});
});
testWithoutContext
(
'handles null AOT snapshot json'
,
()
async
{
final
SizeAnalyzer
sizeAnalyzer
=
SizeAnalyzer
(
fileSystem:
fileSystem
,
logger:
logger
,
appFilenamePattern:
RegExp
(
r'lib.*app\.so'
),
flutterUsage:
TestUsage
(),
);
final
Directory
outputDirectory
=
fileSystem
.
directory
(
'example/out/foo.app'
)..
createSync
(
recursive:
true
);
final
File
invalidAotSizeJson
=
fileSystem
.
file
(
'test.json'
)..
writeAsStringSync
(
'null'
);
final
File
precompilerTrace
=
fileSystem
.
file
(
'trace.json'
);
await
expectLater
(
()
=>
sizeAnalyzer
.
analyzeAotSnapshot
(
outputDirectory:
outputDirectory
,
aotSnapshot:
invalidAotSizeJson
,
precompilerTrace:
precompilerTrace
,
type:
'linux'
,
),
throwsToolExit
());
final
File
apk
=
fileSystem
.
file
(
'test.apk'
)..
writeAsBytesSync
(
ZipEncoder
().
encode
(
Archive
())!);
await
expectLater
(
()
=>
sizeAnalyzer
.
analyzeZipSizeAndAotSnapshot
(
zipFile:
apk
,
aotSnapshot:
invalidAotSizeJson
,
precompilerTrace:
precompilerTrace
,
kind:
'apk'
,
),
throwsToolExit
());
});
}
packages/flutter_tools/test/integration.shard/analyze_size_test.dart
View file @
8d3bc184
...
...
@@ -9,6 +9,7 @@ import 'package:file_testing/file_testing.dart';
import
'package:flutter_tools/src/base/io.dart'
;
import
'../src/common.dart'
;
import
'../src/context.dart'
;
import
'test_utils.dart'
;
const
String
apkDebugMessage
=
'A summary of your APK analysis can be found at: '
;
...
...
@@ -16,7 +17,7 @@ const String iosDebugMessage = 'A summary of your iOS bundle analysis can be fou
const
String
runDevToolsMessage
=
'flutter pub global activate devtools; flutter pub global run devtools '
;
void
main
(
)
{
test
Without
Context
(
'--analyze-size flag produces expected output on hello_world for Android'
,
()
async
{
test
Using
Context
(
'--analyze-size flag produces expected output on hello_world for Android'
,
()
async
{
final
String
workingDirectory
=
fileSystem
.
path
.
join
(
getFlutterRoot
(),
'examples'
,
'hello_world'
);
final
String
flutterBin
=
fileSystem
.
path
.
join
(
getFlutterRoot
(),
'bin'
,
'flutter'
);
final
ProcessResult
result
=
await
processManager
.
run
(<
String
>[
...
...
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