b73f7ed3d4
The find_base_commit program locates the newest commit with a full set of test results. This is a good base for local testing when comparing with the results from the official bots, as all the needed results are there. Change-Id: Ie06020ca98317b82f46589ad6dede37361acf744 Reviewed-on: https://dart-review.googlesource.com/c/81040 Reviewed-by: Alexander Thomas <athom@google.com>
117 lines
4.0 KiB
Dart
Executable File
117 lines
4.0 KiB
Dart
Executable File
#!/usr/bin/env dart
|
|
// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
// Find the newest commit that has a full set of results on the bots.
|
|
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
import 'dart:math';
|
|
|
|
import 'package:args/args.dart';
|
|
import 'package:glob/glob.dart';
|
|
|
|
void main(List<String> args) async {
|
|
final parser = new ArgParser();
|
|
parser.addMultiOption("bot",
|
|
abbr: "b",
|
|
help: "Select the bots matching the glob pattern [option is repeatable]",
|
|
splitCommas: false);
|
|
parser.addOption("branch",
|
|
abbr: "B",
|
|
help: "Select the bots building this branch",
|
|
defaultsTo: "master");
|
|
parser.addOption("count",
|
|
abbr: "c", help: "List this many commits", defaultsTo: "1");
|
|
parser.addFlag("help", help: "Show the program usage.", negatable: false);
|
|
|
|
final options = parser.parse(args);
|
|
if (options["help"]) {
|
|
print("""
|
|
Usage: find_base_commit.dart [OPTION]...
|
|
Find the newest commit that has a full set of results on the bots.
|
|
|
|
The options are as follows:
|
|
|
|
${parser.usage}""");
|
|
return;
|
|
}
|
|
|
|
int count = int.parse(options["count"]);
|
|
final globs = new List<Glob>.from(
|
|
options["bot"].map((String pattern) => new Glob(pattern)));
|
|
|
|
// Download the most recent builds from buildbucket.
|
|
int maxBuilds = 1000;
|
|
final url = Uri.parse(
|
|
"https://cr-buildbucket.appspot.com/_ah/api/buildbucket/v1/search"
|
|
"?bucket=luci.dart.ci.sandbox"
|
|
"&max_builds=$maxBuilds"
|
|
"&status=COMPLETED"
|
|
"&fields=builds(url%2Cparameters_json)");
|
|
final client = new HttpClient();
|
|
final request = await client.getUrl(url).timeout(const Duration(seconds: 30));
|
|
final response = await request.close().timeout(const Duration(seconds: 30));
|
|
final Map<String, dynamic> object = await response
|
|
.transform(new Utf8Decoder())
|
|
.transform(new JsonDecoder())
|
|
.first
|
|
.timeout(const Duration(seconds: 30));
|
|
client.close();
|
|
|
|
// Locate the builds we're interested in and map them to each commit. The
|
|
// builds returned by the API are sorted with the newest first. Since bots
|
|
// don't build back in time and always build the latest commit whenever they
|
|
// can, the first time we see a commit, we know it's newer than all commits
|
|
// we haven't seen yet. The insertion order into the botsForCommits map will
|
|
// then sorted with the newest commit first.
|
|
final builds = object["builds"];
|
|
final botsForCommits = <String, Set<String>>{};
|
|
for (final build in builds) {
|
|
final parameters = jsonDecode(build["parameters_json"]);
|
|
final bot = parameters["builder_name"];
|
|
if (bot.endsWith("-dev") || bot.endsWith("-stable")) {
|
|
// Ignore the -dev and -stable builders. The -try builders aren't in the
|
|
// bucket we're reading.
|
|
continue;
|
|
}
|
|
if (globs.isNotEmpty && !globs.any((glob) => glob.matches(bot))) {
|
|
// Filter way bots we're not interested in.
|
|
continue;
|
|
}
|
|
final properties = parameters["properties"];
|
|
final branch = properties["branch"];
|
|
if (branch != null && branch != "refs/heads/${options['branch']}") {
|
|
// Ignore bots that are building the wrong branch.
|
|
continue;
|
|
}
|
|
final commit = properties["revision"];
|
|
if (commit == null) {
|
|
// Ignore bots that aren't commit based, e.g. fuzz-linux.
|
|
continue;
|
|
}
|
|
final botsForCommit =
|
|
botsForCommits.putIfAbsent(commit, () => new Set<String>());
|
|
botsForCommit.add(bot);
|
|
}
|
|
|
|
if (botsForCommits.isEmpty) {
|
|
print("Failed to locate any commits having run on the bots");
|
|
exitCode = 1;
|
|
return;
|
|
}
|
|
|
|
int maxBots = 0;
|
|
for (final commit in botsForCommits.keys) {
|
|
maxBots = max(maxBots, botsForCommits[commit].length);
|
|
}
|
|
|
|
// List commits run on the most bots.
|
|
for (final commit in botsForCommits.keys
|
|
.where((commit) => botsForCommits[commit].length == maxBots)
|
|
.take(count)) {
|
|
print(commit);
|
|
}
|
|
}
|