[current results] Implement ListTests API call
Change-Id: If0a950f9182ad40f4b3ae9c4804ae4d92619e9f2
Reviewed-on: https://dart-review.googlesource.com/c/dart_ci/+/151244
Reviewed-by: Alexander Thomas <athom@google.com>
diff --git a/current_results/bin/client.dart b/current_results/bin/client.dart
index 1b85b0a..9b183a9 100644
--- a/current_results/bin/client.dart
+++ b/current_results/bin/client.dart
@@ -12,10 +12,11 @@
final runner = CommandRunner<void>(
'client.dart', 'Send gRPC requests to current results server')
..addCommand(QueryCommand())
+ ..addCommand(ListTestsCommand())
..addCommand(FetchCommand())
- ..argParser.addOption('host', help: 'Current results server to query')
+ ..argParser.addOption('host', help: 'current results server to query')
..argParser
- .addOption('port', abbr: 'p', help: 'Port of current results server');
+ .addOption('port', abbr: 'p', help: 'port of current results server');
await runner.run(args);
}
@@ -37,9 +38,9 @@
class QueryCommand extends gRpcCommand {
QueryCommand() {
argParser.addMultiOption('name',
- abbr: 'n', help: 'Test name or prefix to fetch results for');
+ abbr: 'n', help: 'test name or prefix to fetch results for');
argParser.addMultiOption('configuration',
- abbr: 'c', help: 'Configuration to fetch results for');
+ abbr: 'c', help: 'configuration to fetch results for');
}
String get name => 'getResults';
String get description => 'Send a GetResults gRPC request to the server';
@@ -53,6 +54,27 @@
}
}
+class ListTestsCommand extends gRpcCommand {
+ ListTestsCommand() {
+ argParser.addOption('prefix',
+ defaultsTo: '', help: 'test name prefix to fetch test names for');
+ argParser.addOption('limit',
+ defaultsTo: '0',
+ help: 'number of test names starting with prefix to return');
+ }
+
+ String get name => 'listTests';
+ String get description => 'Send a ListTests gRPC request to the server';
+
+ Future<void> runWithChannel(ClientChannel channel) async {
+ final query = ListTestsRequest()
+ ..prefix = argResults['prefix']
+ ..limit = int.parse(argResults['limit']);
+ final result = await QueryClient(channel).listTests(query);
+ print(result.toProto3Json());
+ }
+}
+
class FetchCommand extends gRpcCommand {
String get name => 'fetch';
String get description => 'Send a Fetch gRPC request to the server';
diff --git a/current_results/lib/src/api_impl.dart b/current_results/lib/src/api_impl.dart
index d411f7f..00d03b9 100644
--- a/current_results/lib/src/api_impl.dart
+++ b/current_results/lib/src/api_impl.dart
@@ -25,9 +25,8 @@
@override
Future<ListTestsResponse> listTests(
- ServiceCall call, ListTestsRequest query) async {
- throw UnimplementedError();
- }
+ ServiceCall call, ListTestsRequest query) =>
+ Future.value(current.listTests(query));
@override
Future<ListTestsResponse> listTestPathCompletions(
diff --git a/current_results/lib/src/slice.dart b/current_results/lib/src/slice.dart
index 3c80b65..c910630 100644
--- a/current_results/lib/src/slice.dart
+++ b/current_results/lib/src/slice.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'dart:convert';
+import 'dart:math';
import 'package:collection/collection.dart';
import 'package:grpc/grpc.dart';
@@ -125,4 +126,21 @@
}
return response;
}
+
+ query_api.ListTestsResponse listTests(query_api.ListTestsRequest query) {
+ var limit = min(query.limit, 100000);
+ if (limit == 0) limit = 20;
+ final prefix = query.prefix;
+ final response = query_api.ListTestsResponse();
+ final start = lowerBound(testNames, prefix);
+ final end = min(start + limit, testNames.length);
+ for (final name in testNames.getRange(start, end)) {
+ if (name.startsWith(prefix)) {
+ response.names.add(name);
+ } else {
+ break;
+ }
+ }
+ return response;
+ }
}