blob: 9270fc9cfd175febba60e76ca473e1d81a4ae38d [file] [log] [blame]
// Copyright (c) 2020, 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.
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'src/generated/query.pb.dart';
import 'filter.dart';
const String apiHost = 'current-results-rest-zlujsyuhha-uc.a.run.app';
// Current endpoints proxy is limited to 1 MB response size,
// so we limit results fetched to 4000.
// Implement paging on the service in the future to remove this limit.
const int fetchLimit = 4000;
const int maxFetchedResults = 100 * fetchLimit;
class QueryResults extends ChangeNotifier {
Filter filter;
bool showAll = true;
List<String> names = [];
Map<String, Map<String, int>> counts = {};
Map<String, Map<ChangeInResult, List<Result>>> grouped = {};
bool partialResults = true;
GetResultsResponse resultsObject = GetResultsResponse.create();
void fetchCurrentResults() async {
final client = http.Client();
final resultsQuery = Uri.https(apiHost, 'v1/results',
{'filter': filter.terms.join(','), 'pageSize': '$fetchLimit'});
final resultsResponse = await client.get(resultsQuery);
resultsObject = GetResultsResponse.create()
..mergeFromProto3Json(json.decode(resultsResponse.body));
final results = resultsObject.results;
for (final result in results) {
grouped
.putIfAbsent(result.name, () => <ChangeInResult, List<Result>>{})
.putIfAbsent(ChangeInResult(result), () => <Result>[])
.add(result);
}
for (final name in grouped.keys) {
final count = counts[name] = <String, int>{};
for (final change in grouped[name].keys) {
count.putIfAbsent(change.kind, () => 0);
count[change.kind] += grouped[name][change].length;
}
}
names = grouped.keys.toList()..sort();
partialResults = results.length == fetchLimit;
notifyListeners();
}
}
class ChangeInResult {
final String result;
final String expected;
final bool flaky;
final String text;
bool get matches => result == expected;
String get kind => flaky ? 'flaky' : matches ? 'pass' : 'fail';
ChangeInResult(Result result)
: this._(result.result, result.expected, result.flaky);
ChangeInResult._(this.result, this.expected, this.flaky)
: text = flaky
? "flaky (latest result $result expected $expected"
: "$result (expected $expected)";
@override
String toString() => text;
@override
bool operator ==(Object other) => text == (other as ChangeInResult)?.text;
@override
int get hashCode => text.hashCode;
}
String resultAsCommaSeparated(Result result) => [
result.name,
result.configuration,
result.result,
result.expected,
result.flaky,
result.timeMs
].join(',');
String resultTextHeader = "name,configuration,result,expected,flaky,timeMs";