Use flutter repo for engine golds instead of flutter-engine. (#160556)

Closes https://github.com/flutter/flutter/issues/157206.

I also added a `prefix` that will default to `engine.` to avoid
accidentally stomping on golden names across repos.

/cc @gaaclarke for visibility, @Piinks for visibility.

(I would love to get rid of this "engine copy" of the client as part of
longer-term mono repo deduplication).
This commit is contained in:
Matan Lurey 2025-01-06 19:37:36 -08:00 committed by GitHub
parent 95c1bc1c3e
commit cda3515126
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 70 additions and 7 deletions

View File

@ -173,7 +173,7 @@ String get _flutterBuildPath {
} }
void main() async { void main() async {
final ImageComparer comparer = await ImageComparer.create(); final ImageComparer comparer = await ImageComparer.create(verbose: true);
testNoCrashes(); testNoCrashes();

View File

@ -20,8 +20,8 @@ const String _kGoldctlKey = 'GOLDCTL';
const String _kPresubmitEnvName = 'GOLD_TRYJOB'; const String _kPresubmitEnvName = 'GOLD_TRYJOB';
const String _kLuciEnvName = 'LUCI_CONTEXT'; const String _kLuciEnvName = 'LUCI_CONTEXT';
const String _skiaGoldHost = 'https://flutter-engine-gold.skia.org'; const String _skiaGoldHost = 'https://flutter-gold.skia.org';
const String _instance = 'flutter-engine'; const String _instance = 'flutter';
/// Uploads images and makes baseline requests to Skia Gold. /// Uploads images and makes baseline requests to Skia Gold.
/// ///
@ -47,10 +47,16 @@ interface class SkiaGoldClient {
/// spammy for regular use. /// spammy for regular use.
factory SkiaGoldClient( factory SkiaGoldClient(
io.Directory workDirectory, { io.Directory workDirectory, {
String prefix = 'engine.',
Map<String, String>? dimensions, Map<String, String>? dimensions,
bool verbose = false, bool verbose = false,
}) { }) {
return SkiaGoldClient.forTesting(workDirectory, dimensions: dimensions, verbose: verbose); return SkiaGoldClient.forTesting(
workDirectory,
dimensions: dimensions,
verbose: verbose,
prefix: prefix,
);
} }
/// Creates a [SkiaGoldClient] for testing. /// Creates a [SkiaGoldClient] for testing.
@ -73,6 +79,7 @@ interface class SkiaGoldClient {
this.workDirectory, { this.workDirectory, {
this.dimensions, this.dimensions,
this.verbose = false, this.verbose = false,
String? prefix,
io.HttpClient? httpClient, io.HttpClient? httpClient,
ProcessManager? processManager, ProcessManager? processManager,
StringSink? stderr, StringSink? stderr,
@ -80,6 +87,7 @@ interface class SkiaGoldClient {
Engine? engineRoot, Engine? engineRoot,
}) : httpClient = httpClient ?? io.HttpClient(), }) : httpClient = httpClient ?? io.HttpClient(),
process = processManager ?? const LocalProcessManager(), process = processManager ?? const LocalProcessManager(),
_prefix = prefix,
_stderr = stderr ?? io.stderr, _stderr = stderr ?? io.stderr,
_environment = environment ?? io.Platform.environment, _environment = environment ?? io.Platform.environment,
_engineRoot = engineRoot ?? Engine.findWithin() { _engineRoot = engineRoot ?? Engine.findWithin() {
@ -166,6 +174,9 @@ interface class SkiaGoldClient {
/// client will create image and JSON files for the `goldctl` tool to use. /// client will create image and JSON files for the `goldctl` tool to use.
final io.Directory workDirectory; final io.Directory workDirectory;
/// Prefix to add to all test names, if any.
final String? _prefix;
String get _tempPath => path.join(workDirectory.path, 'temp'); String get _tempPath => path.join(workDirectory.path, 'temp');
String get _keysPath => path.join(workDirectory.path, 'keys.json'); String get _keysPath => path.join(workDirectory.path, 'keys.json');
String get _failuresPath => path.join(workDirectory.path, 'failures.json'); String get _failuresPath => path.join(workDirectory.path, 'failures.json');
@ -345,6 +356,11 @@ interface class SkiaGoldClient {
// Clean the test name to remove the file extension. // Clean the test name to remove the file extension.
testName = path.basenameWithoutExtension(testName); testName = path.basenameWithoutExtension(testName);
// Add a prefix to avoid repo-wide conflicts.
if (_prefix != null) {
testName = '$_prefix$testName';
}
// In release branches, we add a unique test suffix to the test name. // In release branches, we add a unique test suffix to the test name.
// For example "testName" -> "testName_Release_3_21". // For example "testName" -> "testName_Release_3_21".
// See ../README.md#release-testing for more information. // See ../README.md#release-testing for more information.
@ -408,7 +424,7 @@ interface class SkiaGoldClient {
..writeln('testing. Golden file images in flutter/engine are triaged ') ..writeln('testing. Golden file images in flutter/engine are triaged ')
..writeln('in pre-submit during code review for the given PR.') ..writeln('in pre-submit during code review for the given PR.')
..writeln() ..writeln()
..writeln('Visit https://flutter-engine-gold.skia.org/ to view and approve ') ..writeln('Visit https://flutter-gold.skia.org/ to view and approve ')
..writeln('the image(s), or revert the associated change. For more ') ..writeln('the image(s), or revert the associated change. For more ')
..writeln('information, visit the wiki: ') ..writeln('information, visit the wiki: ')
..writeln( ..writeln(

View File

@ -22,7 +22,7 @@ void main() {
const Map<String, String> presubmitEnv = <String, String>{ const Map<String, String> presubmitEnv = <String, String>{
'GIT_BRANCH': 'master', 'GIT_BRANCH': 'master',
'GOLDCTL': 'python tools/goldctl.py', 'GOLDCTL': 'python tools/goldctl.py',
'GOLD_TRYJOB': 'flutter/engine/1234567890', 'GOLD_TRYJOB': 'flutter/flutter/1234567890',
'LOGDOG_STREAM_PREFIX': 'buildbucket/cr-buildbucket.appspot.com/1234567890/+/logdog', 'LOGDOG_STREAM_PREFIX': 'buildbucket/cr-buildbucket.appspot.com/1234567890/+/logdog',
'LUCI_CONTEXT': '{}', 'LUCI_CONTEXT': '{}',
}; };
@ -50,6 +50,7 @@ void main() {
required Map<String, String> environment, required Map<String, String> environment,
ReleaseVersion? engineVersion, ReleaseVersion? engineVersion,
Map<String, String>? dimensions, Map<String, String>? dimensions,
String? prefix,
bool verbose = false, bool verbose = false,
io.ProcessResult Function(List<String> command) onRun = _runUnhandled, io.ProcessResult Function(List<String> command) onRun = _runUnhandled,
}) { }) {
@ -62,6 +63,7 @@ void main() {
verbose: verbose, verbose: verbose,
stderr: fixture.outputSink, stderr: fixture.outputSink,
environment: environment, environment: environment,
prefix: prefix,
); );
} }
@ -306,6 +308,51 @@ void main() {
} }
}); });
test('addImg uses prefix, if specified', () async {
final _TestFixture fixture = _TestFixture();
try {
final SkiaGoldClient client = createClient(
fixture,
environment: presubmitEnv,
prefix: 'engine.',
onRun: (List<String> command) {
if (command case ['git', ...]) {
return io.ProcessResult(0, 0, mockCommitHash, '');
}
if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
return io.ProcessResult(0, 0, '', '');
}
expect(command, <String>[
'python tools/goldctl.py',
'imgtest',
'add',
'--work-dir',
p.join(fixture.workDirectory.path, 'temp'),
'--test-name',
'engine.test-name',
'--png-file',
p.join(fixture.workDirectory.path, 'temp', 'golden.png'),
'--add-test-optional-key',
'image_matching_algorithm:fuzzy',
'--add-test-optional-key',
'fuzzy_max_different_pixels:10',
'--add-test-optional-key',
'fuzzy_pixel_delta_threshold:0',
]);
return io.ProcessResult(0, 0, '', '');
},
);
await client.addImg(
'test-name.foo',
io.File(p.join(fixture.workDirectory.path, 'temp', 'golden.png')),
screenshotSize: 1000,
);
} finally {
fixture.dispose();
}
});
test('addImg [pre-submit] executes successfully with a release version', () async { test('addImg [pre-submit] executes successfully with a release version', () async {
// Adds a suffix of "_Release_3_21" to the test name. // Adds a suffix of "_Release_3_21" to the test name.
final _TestFixture fixture = _TestFixture( final _TestFixture fixture = _TestFixture(
@ -639,7 +686,7 @@ void main() {
final String hash = client.getTraceID('test-name'); final String hash = client.getTraceID('test-name');
fixture.httpClient.setJsonResponse( fixture.httpClient.setJsonResponse(
Uri.parse('https://flutter-engine-gold.skia.org/json/v2/latestpositivedigest/$hash'), Uri.parse('https://flutter-gold.skia.org/json/v2/latestpositivedigest/$hash'),
<String, Object?>{'digest': 'digest'}, <String, Object?>{'digest': 'digest'},
); );