-
Notifications
You must be signed in to change notification settings - Fork 26.7k
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
[flutter_tools] migrate flutter_goldens, flutter_goldens client to null-safety #64201
Changes from 3 commits
68d093a
cdb8f90
b153d57
37aa5ee
5e4140c
1ac31ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
// @dart = 2.8 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This test uses too much mockito |
||
import 'dart:async'; | ||
import 'dart:convert'; | ||
import 'dart:core'; | ||
|
@@ -75,6 +76,7 @@ void main() { | |
process: process, | ||
platform: platform, | ||
httpClient: mockHttpClient, | ||
ci: ContinuousIntegrationEnvironment.luci, | ||
); | ||
}); | ||
|
||
|
@@ -148,6 +150,7 @@ void main() { | |
process: process, | ||
platform: platform, | ||
httpClient: mockHttpClient, | ||
ci: ContinuousIntegrationEnvironment.luci | ||
); | ||
|
||
when(process.run( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,13 +35,9 @@ class SkiaGoldClient { | |
this.fs = const LocalFileSystem(), | ||
this.process = const LocalProcessManager(), | ||
this.platform = const LocalPlatform(), | ||
this.ci, | ||
io.HttpClient httpClient, | ||
}) : assert(workDirectory != null), | ||
assert(fs != null), | ||
assert(process != null), | ||
assert(platform != null), | ||
httpClient = httpClient ?? io.HttpClient(); | ||
required this.ci, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I decided to make this required since we don't handle null in the switch below. |
||
io.HttpClient? httpClient, | ||
}) : httpClient = httpClient ?? io.HttpClient(); | ||
|
||
/// The file system to use for storing the local clone of the repository. | ||
/// | ||
|
@@ -83,7 +79,7 @@ class SkiaGoldClient { | |
/// [_UnauthorizedFlutterPreSubmitComparator] to test against golden masters | ||
/// maintained in the Flutter Gold dashboard. | ||
Map<String, List<String>> get expectations => _expectations; | ||
Map<String, List<String>> _expectations; | ||
late Map<String, List<String>> _expectations; | ||
|
||
/// The local [Directory] where the Flutter repository is hosted. | ||
/// | ||
|
@@ -93,13 +89,13 @@ class SkiaGoldClient { | |
/// The path to the local [Directory] where the goldctl tool is hosted. | ||
/// | ||
/// Uses the [platform] environment in this implementation. | ||
String/*!*/ get _goldctl => platform.environment[_kGoldctlKey]; | ||
String get _goldctl => platform.environment[_kGoldctlKey]!; | ||
|
||
/// The path to the local [Directory] where the service account key is | ||
/// hosted. | ||
/// | ||
/// Uses the [platform] environment in this implementation. | ||
String/*!*/ get _serviceAccount => platform.environment[_kServiceAccountKey]; | ||
String get _serviceAccount => platform.environment[_kServiceAccountKey]!; | ||
|
||
/// Prepares the local work space for golden file testing and calls the | ||
/// goldctl `auth` command. | ||
|
@@ -116,9 +112,9 @@ class SkiaGoldClient { | |
return; | ||
|
||
List<String> authArguments; | ||
/*late*/ String failureContext; | ||
String failureContext; | ||
|
||
switch (ci/*!*/) { | ||
switch (ci) { | ||
case ContinuousIntegrationEnvironment.luci: | ||
authArguments = <String>[ | ||
'auth', | ||
|
@@ -267,9 +263,6 @@ class SkiaGoldClient { | |
/// The [testName] and [goldenFile] parameters reference the current | ||
/// comparison being evaluated by the [FlutterPostSubmitFileComparator]. | ||
Future<bool> imgtestAdd(String testName, File goldenFile) async { | ||
assert(testName != null); | ||
assert(goldenFile != null); | ||
|
||
final List<String> imgtestArguments = <String>[ | ||
'imgtest', 'add', | ||
'--work-dir', workDirectory | ||
|
@@ -361,9 +354,6 @@ class SkiaGoldClient { | |
/// The [testName] and [goldenFile] parameters reference the current | ||
/// comparison being evaluated by the [_AuthorizedFlutterPreSubmitComparator]. | ||
Future<void> tryjobAdd(String testName, File goldenFile) async { | ||
assert(testName != null); | ||
assert(goldenFile != null); | ||
|
||
final List<String> imgtestArguments = <String>[ | ||
'imgtest', 'add', | ||
'--work-dir', workDirectory | ||
|
@@ -410,9 +400,6 @@ class SkiaGoldClient { | |
/// comparison being evaluated by the | ||
/// [_UnauthorizedFlutterPreSubmitComparator]. | ||
Future<bool> imgtestCheck(String testName, File goldenFile) async { | ||
assert(testName != null); | ||
assert(goldenFile != null); | ||
|
||
final List<String> imgtestArguments = <String>[ | ||
'imgtest', 'check', | ||
'--work-dir', workDirectory | ||
|
@@ -440,15 +427,15 @@ class SkiaGoldClient { | |
); | ||
const String mainKey = 'master'; | ||
const String temporaryKey = 'master_str'; | ||
String rawResponse; | ||
late String rawResponse; | ||
try { | ||
final io.HttpClientRequest request = await httpClient.getUrl(requestForExpectations); | ||
final io.HttpClientResponse response = await request.close(); | ||
rawResponse = await utf8.decodeStream(response); | ||
final dynamic jsonResponse = json.decode(rawResponse); | ||
if (jsonResponse is! Map<String, dynamic>) | ||
throw const FormatException('Skia gold expectations do not match expected format.'); | ||
final Map<String, dynamic> skiaJson = (jsonResponse[mainKey] ?? jsonResponse[temporaryKey]) as Map<String, dynamic>; | ||
final Map<String, dynamic>? skiaJson = (jsonResponse[mainKey] ?? jsonResponse[temporaryKey]) as Map<String, dynamic>?; | ||
if (skiaJson == null) | ||
throw FormatException('Skia gold expectations are missing the "$mainKey" key (and also doesn\'t have "$temporaryKey")! Available keys: ${jsonResponse.keys.join(", ")}'); | ||
skiaJson.forEach((String key, dynamic value) { | ||
|
@@ -506,7 +493,7 @@ class SkiaGoldClient { | |
Future<bool> testIsIgnoredForPullRequest(String pullRequest, String testName) async { | ||
bool ignoreIsActive = false; | ||
testName = cleanTestName(testName); | ||
String rawResponse; | ||
late String rawResponse; | ||
await io.HttpOverrides.runWithHttpOverrides<Future<void>>(() async { | ||
final Uri requestForIgnores = Uri.parse( | ||
'https://flutter-gold.skia.org/json/ignores' | ||
|
@@ -565,7 +552,7 @@ class SkiaGoldClient { | |
Future<bool> isValidDigestForExpectation(String expectation, String testName) async { | ||
bool isValid = false; | ||
testName = cleanTestName(testName); | ||
String rawResponse; | ||
late String rawResponse; | ||
await io.HttpOverrides.runWithHttpOverrides<Future<void>>(() async { | ||
final Uri requestForDigest = Uri.parse( | ||
'https://flutter-gold.skia.org/json/details?test=$testName&digest=$expectation' | ||
|
@@ -653,20 +640,20 @@ class SkiaGoldClient { | |
/// Returns a list of arguments for initializing a tryjob based on the testing | ||
/// environment. | ||
List<String> getCIArguments() { | ||
/*late*/ String/*!*/ pullRequest; | ||
/*late*/ String/*!*/ jobId; | ||
/*late*/ String cis; | ||
String pullRequest; | ||
String jobId; | ||
String cis; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yay definite assignment analysis |
||
|
||
switch (ci/*!*/) { | ||
switch (ci) { | ||
case ContinuousIntegrationEnvironment.luci: | ||
jobId = platform.environment['LOGDOG_STREAM_PREFIX'].split('/').last; | ||
final List<String> refs = platform.environment['GOLD_TRYJOB'].split('/'); | ||
jobId = platform.environment['LOGDOG_STREAM_PREFIX']!.split('/').last; | ||
final List<String> refs = platform.environment['GOLD_TRYJOB']!.split('/'); | ||
pullRequest = refs[refs.length - 2]; | ||
cis = 'buildbucket'; | ||
break; | ||
case ContinuousIntegrationEnvironment.cirrus: | ||
pullRequest = platform.environment['CIRRUS_PR']; | ||
jobId = platform.environment['CIRRUS_TASK_ID']; | ||
pullRequest = platform.environment['CIRRUS_PR']!; | ||
jobId = platform.environment['CIRRUS_TASK_ID']!; | ||
cis = 'cirrus'; | ||
break; | ||
} | ||
|
@@ -685,17 +672,17 @@ class SkiaGoldHttpOverrides extends io.HttpOverrides {} | |
/// A digest returned from a request to the Flutter Gold dashboard. | ||
class SkiaGoldDigest { | ||
const SkiaGoldDigest({ | ||
this.imageHash, | ||
this.paramSet, | ||
this.testName, | ||
this.status, | ||
required this.imageHash, | ||
required this.paramSet, | ||
required this.testName, | ||
required this.status, | ||
}); | ||
|
||
/// Create a digest from requested JSON. | ||
factory SkiaGoldDigest.fromJson(Map<String, dynamic> json) { | ||
return SkiaGoldDigest( | ||
imageHash: json['digest'] as String, | ||
paramSet: Map<String, dynamic>.from(json['paramset'] as Map<String, dynamic> ?? | ||
paramSet: Map<String, dynamic>.from(json['paramset'] as Map<String, dynamic>? ?? | ||
<String, List<String>>{ | ||
'Platform': <String>[], | ||
'Browser' : <String>[], | ||
|
@@ -706,16 +693,16 @@ class SkiaGoldDigest { | |
} | ||
|
||
/// Unique identifier for the image associated with the digest. | ||
final String/*!*/ imageHash; | ||
final String imageHash; | ||
|
||
/// Parameter set for the given test, e.g. Platform : Windows. | ||
final Map<String, dynamic>/*!*/ paramSet; | ||
final Map<String, dynamic> paramSet; | ||
|
||
/// Test name associated with the digest, e.g. positive or un-triaged. | ||
final String/*!*/ testName; | ||
final String testName; | ||
|
||
/// Status of the given digest, e.g. positive or un-triaged. | ||
final String/*!*/ status; | ||
final String status; | ||
|
||
/// Validates a given digest against the current testing conditions. | ||
bool isValid(Platform platform, String name, String expectation) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The local comparator is used in a non-ci environment, so neither of these would be correct. 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WDUT about
ContinuousIntegrationEnvironment.none
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM. The switch statements will want it to be accounted for, it'll just be a pass through then. :) Thanks!