[baseline] Add support to duplicate configurations
Bug: b/270918398
Change-Id: Ib125d48369ba86c527b28ee992d3fe380044928f
Reviewed-on: https://dart-review.googlesource.com/c/dart_ci/+/286880
Commit-Queue: William Hesse <whesse@google.com>
Auto-Submit: Alexander Thomas <athom@google.com>
Reviewed-by: William Hesse <whesse@google.com>
diff --git a/baseline/lib/baseline.dart b/baseline/lib/baseline.dart
index fd8653b..43a6a41 100644
--- a/baseline/lib/baseline.dart
+++ b/baseline/lib/baseline.dart
@@ -60,7 +60,7 @@
String channel,
Set<String> suites,
String target,
- Map<String, String> configs,
+ Map<String, List<String>> configs,
bool dryRun,
ConfigurationMapping mapping,
String resultBase) async {
@@ -74,23 +74,25 @@
for (var json in LineSplitter.split(results)
.map(jsonDecode)
.cast<Map<String, dynamic>>()) {
- var configuration = mapping(json['configuration'], configs);
- if (configuration == null) {
+ var configurations = mapping(json['configuration'], configs);
+ if (configurations == null) {
continue;
}
- if (suites.isNotEmpty && !suites.contains(json['suite'])) continue;
- json['configuration'] = configuration;
- json['build_number'] = '0';
- json['previous_build_number'] = '0';
- json['builder_name'] = target;
- json['flaky'] = false;
- json['previous_flaky'] = false;
+ for (var configuration in configurations) {
+ if (suites.isNotEmpty && !suites.contains(json['suite'])) continue;
+ json['configuration'] = configuration;
+ json['build_number'] = '0';
+ json['previous_build_number'] = '0';
+ json['builder_name'] = target;
+ json['flaky'] = false;
+ json['previous_flaky'] = false;
- var encoded = jsonEncode(json);
- modifiedResults.writeln(encoded);
- modifiedResultsPerConfig
- .putIfAbsent(configuration, () => StringBuffer())
- .writeln(encoded);
+ var encoded = jsonEncode(json);
+ modifiedResults.writeln(encoded);
+ modifiedResultsPerConfig
+ .putIfAbsent(configuration, () => StringBuffer())
+ .writeln(encoded);
+ }
if (dryRun) break;
}
}
diff --git a/baseline/lib/options.dart b/baseline/lib/options.dart
index d4aea52..56b3992 100644
--- a/baseline/lib/options.dart
+++ b/baseline/lib/options.dart
@@ -8,7 +8,7 @@
class BaselineOptions {
final List<String> builders;
- final Map<String, String> configs;
+ final Map<String, List<String>> configs;
final bool dryRun;
final List<String> channels;
final ConfigurationMapping mapping;
@@ -64,14 +64,15 @@
var mapping = parsed['ignore-unmapped']
? ConfigurationMapping.relaxed
: ConfigurationMapping.strict;
- var configs = const <String, String>{};
+ var configs = const <String, List<String>>{};
final configMapping = parsed['config-mapping'] as List<String>;
if (configMapping.length == 1 && configMapping.first == '*') {
mapping = ConfigurationMapping.none;
} else {
- configs = {
- for (var v in configMapping.map((c) => c.split(':'))) v[0]: v[1]
- };
+ configs = {};
+ for (var mapping in configMapping.map((c) => c.split(':'))) {
+ configs.putIfAbsent(mapping.first, () => []).add(mapping.last);
+ }
}
final dryRun = parsed['dry-run'];
final channels = parsed['channel'];
@@ -82,13 +83,15 @@
}
}
-String? _strict(String configuration, Map<String, String> configs) =>
+List<String>? _strict(
+ String configuration, Map<String, List<String>> configs) =>
configs[configuration] ??
(throw Exception("Missing configuration mapping for $configuration"));
-String? _relaxed(String configuration, Map<String, String> configs) =>
+List<String>? _relaxed(
+ String configuration, Map<String, List<String>> configs) =>
configs[configuration];
-String? _none(String configuration, Map<String, String> configs) =>
- configuration;
+List<String>? _none(String configuration, Map<String, List<String>> configs) =>
+ [configuration];
enum ConfigurationMapping {
none(_none),
@@ -96,9 +99,9 @@
relaxed(_relaxed);
const ConfigurationMapping(this.mapping);
- final String? Function(String configuration, Map<String, String> configs)
- mapping;
+ final List<String>? Function(
+ String configuration, Map<String, List<String>> configs) mapping;
- String? call(String configuration, Map<String, String> configs) =>
+ List<String>? call(String configuration, Map<String, List<String>> configs) =>
mapping(configuration, configs);
}
diff --git a/baseline/test/baseline_test.dart b/baseline/test/baseline_test.dart
index e7b83b2..057c3ce 100644
--- a/baseline/test/baseline_test.dart
+++ b/baseline/test/baseline_test.dart
@@ -269,6 +269,39 @@
...testData,
});
});
+
+ test('baseline split configs', () async {
+ final newBuilderStableResults = [
+ '{"build_number":"0","previous_build_number":"0","builder_name":"new-builder-stable","configuration":"new-config1","suite":"suite1","test_name":"test1","result":"PASS","flaky":false,"previous_flaky":false}',
+ '{"build_number":"0","previous_build_number":"0","builder_name":"new-builder-stable","configuration":"new-config2","suite":"suite1","test_name":"test1","result":"PASS","flaky":false,"previous_flaky":false}',
+ ];
+ final newBuilderResults = [
+ '{"build_number":"0","previous_build_number":"0","builder_name":"new-builder","configuration":"new-config1","suite":"suite1","test_name":"test1","result":"FAIL","flaky":false,"previous_flaky":false}',
+ '{"build_number":"0","previous_build_number":"0","builder_name":"new-builder","configuration":"new-config2","suite":"suite1","test_name":"test1","result":"FAIL","flaky":false,"previous_flaky":false}',
+ ];
+ await baselineTest([
+ '--builders=builder,builder2',
+ '--target=new-builder',
+ '--channel=main,stable',
+ '--config-mapping=config1:new-config1,config1:new-config2,',
+ '--ignore-unmapped',
+ ], {
+ 'builders/new-builder-stable/0/results.json':
+ unorderedEquals(newBuilderStableResults),
+ 'builders/new-builder-stable/latest': ['0'],
+ 'builders/new-builder/0/results.json': unorderedEquals(newBuilderResults),
+ 'builders/new-builder/latest': ['0'],
+ 'configuration/main/new-config1/0/results.json': [newBuilderResults[0]],
+ 'configuration/stable/new-config1/0/results.json': [
+ newBuilderStableResults[0]
+ ],
+ 'configuration/main/new-config2/0/results.json': [newBuilderResults[1]],
+ 'configuration/stable/new-config2/0/results.json': [
+ newBuilderStableResults[1]
+ ],
+ ...testData,
+ });
+ });
}
Future<void> baselineTest(
diff --git a/baseline/test/options_test.dart b/baseline/test/options_test.dart
index ed9d9c1..8fdb68d 100644
--- a/baseline/test/options_test.dart
+++ b/baseline/test/options_test.dart
@@ -33,7 +33,18 @@
test('config-mapping', () {
var options = BaselineOptions.parse(['-mc:d,e:f', ..._builders]);
- expect(options.configs, {'c': 'd', 'e': 'f'});
+ expect(options.configs, {
+ 'c': ['d'],
+ 'e': ['f']
+ });
+ expect(options.mapping, ConfigurationMapping.strict);
+ });
+
+ test('config-mapping-multiple', () {
+ var options = BaselineOptions.parse(['-ma:b,a:c', ..._builders]);
+ expect(options.configs, {
+ 'a': ['b', 'c']
+ });
expect(options.mapping, ConfigurationMapping.strict);
});
@@ -64,18 +75,41 @@
});
test('mapping: strict', () {
- expect(ConfigurationMapping.strict('foo', {'foo': 'bar'}), 'bar');
- expect(() => ConfigurationMapping.strict('oof', {'foo': 'bar'}),
+ expect(
+ ConfigurationMapping.strict('foo', {
+ 'foo': ['bar']
+ }),
+ 'bar');
+ expect(
+ () => ConfigurationMapping.strict('oof', {
+ 'foo': ['bar']
+ }),
throwsException);
});
test('mapping: relaxed', () {
- expect(ConfigurationMapping.relaxed('foo', {'foo': 'bar'}), 'bar');
- expect(ConfigurationMapping.relaxed('oof', {'foo': 'bar'}), null);
+ expect(
+ ConfigurationMapping.relaxed('foo', {
+ 'foo': ['bar']
+ }),
+ 'bar');
+ expect(
+ ConfigurationMapping.relaxed('oof', {
+ 'foo': ['bar']
+ }),
+ null);
});
test('mapping: none', () {
- expect(ConfigurationMapping.none('foo', {'foo': 'bar'}), 'foo');
- expect(ConfigurationMapping.none('oof', {'foo': 'bar'}), 'oof');
+ expect(
+ ConfigurationMapping.none('foo', {
+ 'foo': ['bar']
+ }),
+ 'foo');
+ expect(
+ ConfigurationMapping.none('oof', {
+ 'foo': ['bar']
+ }),
+ 'oof');
});
}