mirror of
https://github.com/flutter/packages.git
synced 2025-06-24 17:18:57 +08:00
[metric_center] Migrate code to null safety (#439)
This commit is contained in:
@ -1,3 +1,7 @@
|
||||
# 1.0.0
|
||||
|
||||
- Null safety support
|
||||
|
||||
# 0.1.1
|
||||
|
||||
- Update packages to null safe
|
||||
|
@ -16,11 +16,11 @@ class MetricPoint extends Equatable {
|
||||
/// Creates a new data point.
|
||||
MetricPoint(
|
||||
this.value,
|
||||
Map<String, String> tags,
|
||||
Map<String, String?> tags,
|
||||
) : _tags = SplayTreeMap<String, String>.from(tags);
|
||||
|
||||
/// Can store integer values.
|
||||
final double value;
|
||||
final double? value;
|
||||
|
||||
/// Test name, unit, timestamp, configs, git revision, ..., in sorted order.
|
||||
UnmodifiableMapView<String, String> get tags =>
|
||||
@ -43,7 +43,7 @@ class MetricPoint extends Equatable {
|
||||
final SplayTreeMap<String, String> _tags;
|
||||
|
||||
@override
|
||||
List<Object> get props => <Object>[value, tags];
|
||||
List<Object?> get props => <Object?>[value, tags];
|
||||
}
|
||||
|
||||
/// Interface to write [MetricPoint].
|
||||
|
@ -82,7 +82,7 @@ class GcsLock {
|
||||
await _api.objects.delete(_bucketName, lockFileName);
|
||||
}
|
||||
|
||||
StorageApi _api;
|
||||
late StorageApi _api;
|
||||
|
||||
final String _bucketName;
|
||||
final AuthClient _client;
|
||||
|
@ -50,21 +50,21 @@ void _parseAnItem(
|
||||
};
|
||||
for (final String subResult in item.keys) {
|
||||
if (!_kNonNumericalValueSubResults.contains(subResult)) {
|
||||
num rawValue;
|
||||
num? rawValue;
|
||||
try {
|
||||
rawValue = item[subResult] as num;
|
||||
rawValue = item[subResult] as num?;
|
||||
} catch (e) {
|
||||
print(
|
||||
'$subResult: ${item[subResult]} (${item[subResult].runtimeType}) is not a number');
|
||||
rethrow;
|
||||
}
|
||||
|
||||
final double value =
|
||||
rawValue is int ? rawValue.toDouble() : rawValue as double;
|
||||
final double? value =
|
||||
rawValue is int ? rawValue.toDouble() : rawValue as double?;
|
||||
points.add(
|
||||
MetricPoint(
|
||||
value,
|
||||
<String, String>{kNameKey: name, kSubResultKey: subResult}
|
||||
<String, String?>{kNameKey: name, kSubResultKey: subResult}
|
||||
..addAll(context)
|
||||
..addAll(
|
||||
subResult.endsWith('time') ? timeUnitMap : <String, String>{}),
|
||||
|
@ -48,15 +48,15 @@ import 'gcs_lock.dart';
|
||||
/// ```
|
||||
class SkiaPerfPoint extends MetricPoint {
|
||||
SkiaPerfPoint._(this.githubRepo, this.gitHash, this.testName, this.subResult,
|
||||
double value, this._options, this.jsonUrl)
|
||||
double? value, this._options, this.jsonUrl)
|
||||
: assert(_options[kGithubRepoKey] == null),
|
||||
assert(_options[kGitRevisionKey] == null),
|
||||
assert(_options[kNameKey] == null),
|
||||
super(
|
||||
value,
|
||||
<String, String>{}
|
||||
<String, String?>{}
|
||||
..addAll(_options)
|
||||
..addAll(<String, String>{
|
||||
..addAll(<String, String?>{
|
||||
kGithubRepoKey: githubRepo,
|
||||
kGitRevisionKey: gitHash,
|
||||
kNameKey: testName,
|
||||
@ -78,9 +78,9 @@ class SkiaPerfPoint extends MetricPoint {
|
||||
/// Skia perf will use the git revision's date instead of this date tag in
|
||||
/// the time axis.
|
||||
factory SkiaPerfPoint.fromPoint(MetricPoint p) {
|
||||
final String githubRepo = p.tags[kGithubRepoKey];
|
||||
final String gitHash = p.tags[kGitRevisionKey];
|
||||
final String name = p.tags[kNameKey];
|
||||
final String? githubRepo = p.tags[kGithubRepoKey];
|
||||
final String? gitHash = p.tags[kGitRevisionKey];
|
||||
final String? name = p.tags[kNameKey];
|
||||
|
||||
if (githubRepo == null || gitHash == null || name == null) {
|
||||
throw '$kGithubRepoKey, $kGitRevisionKey, $kNameKey must be set in'
|
||||
@ -113,7 +113,7 @@ class SkiaPerfPoint extends MetricPoint {
|
||||
final String githubRepo;
|
||||
|
||||
/// SHA such as 'ad20d368ffa09559754e4b2b5c12951341ca3b2d'
|
||||
final String gitHash;
|
||||
final String? gitHash;
|
||||
|
||||
/// For Flutter devicelab, this is the task name (e.g.,
|
||||
/// 'flutter_gallery__transition_perf'); for Google benchmark, this is the
|
||||
@ -138,7 +138,7 @@ class SkiaPerfPoint extends MetricPoint {
|
||||
/// The url to the Skia perf json file in the Google Cloud Storage bucket.
|
||||
///
|
||||
/// This can be null if the point has been stored in the bucket yet.
|
||||
final String jsonUrl;
|
||||
final String? jsonUrl;
|
||||
|
||||
Map<String, dynamic> _toSubResultJson() {
|
||||
return <String, dynamic>{
|
||||
@ -260,7 +260,7 @@ class SkiaPerfGcsAdaptor {
|
||||
}
|
||||
|
||||
Future<List<SkiaPerfPoint>> _readPointsWithoutRetry(String objectName) async {
|
||||
ObjectInfo info;
|
||||
ObjectInfo? info;
|
||||
|
||||
try {
|
||||
info = await _gcsBucket.info(objectName);
|
||||
@ -282,10 +282,10 @@ class SkiaPerfGcsAdaptor {
|
||||
|
||||
final String firstGcsNameComponent = objectName.split('/')[0];
|
||||
_populateGcsNameToGithubRepoMapIfNeeded();
|
||||
final String githubRepo = _gcsNameToGithubRepo[firstGcsNameComponent];
|
||||
final String githubRepo = _gcsNameToGithubRepo[firstGcsNameComponent]!;
|
||||
assert(githubRepo != null);
|
||||
|
||||
final String gitHash = decodedJson[kSkiaPerfGitHashKey] as String;
|
||||
final String? gitHash = decodedJson[kSkiaPerfGitHashKey] as String?;
|
||||
final Map<String, dynamic> results =
|
||||
decodedJson[kSkiaPerfResultsKey] as Map<String, dynamic>;
|
||||
for (final String name in results.keys) {
|
||||
@ -298,7 +298,7 @@ class SkiaPerfGcsAdaptor {
|
||||
gitHash,
|
||||
name,
|
||||
subResult,
|
||||
subResultMap[subResult] as double,
|
||||
subResultMap[subResult] as double?,
|
||||
(subResultMap[kSkiaPerfOptionsKey] as Map<String, dynamic>)
|
||||
.cast<String, String>(),
|
||||
info.downloadLink.toString(),
|
||||
@ -317,9 +317,9 @@ class SkiaPerfGcsAdaptor {
|
||||
/// json files in the future to scale up the system if too many writes are
|
||||
/// competing for the same json file.
|
||||
static Future<String> computeObjectName(
|
||||
String githubRepo, String revision, DateTime commitTime) async {
|
||||
String githubRepo, String? revision, DateTime commitTime) async {
|
||||
assert(_githubRepoToGcsName[githubRepo] != null);
|
||||
final String topComponent = _githubRepoToGcsName[githubRepo];
|
||||
final String? topComponent = _githubRepoToGcsName[githubRepo];
|
||||
// [commitTime] is not guranteed to be UTC. Ensure it is so all results
|
||||
// pushed to GCS are the same timezone.
|
||||
final DateTime commitUtcTime = commitTime.toUtc();
|
||||
@ -334,12 +334,12 @@ class SkiaPerfGcsAdaptor {
|
||||
kFlutterFrameworkRepo: 'flutter-flutter',
|
||||
kFlutterEngineRepo: 'flutter-engine',
|
||||
};
|
||||
static final Map<String, String> _gcsNameToGithubRepo = <String, String>{};
|
||||
static final Map<String?, String> _gcsNameToGithubRepo = <String?, String>{};
|
||||
|
||||
static void _populateGcsNameToGithubRepoMapIfNeeded() {
|
||||
if (_gcsNameToGithubRepo.isEmpty) {
|
||||
for (final String repo in _githubRepoToGcsName.keys) {
|
||||
final String gcsName = _githubRepoToGcsName[repo];
|
||||
final String? gcsName = _githubRepoToGcsName[repo];
|
||||
assert(_gcsNameToGithubRepo[gcsName] == null);
|
||||
_gcsNameToGithubRepo[gcsName] = repo;
|
||||
}
|
||||
@ -396,43 +396,43 @@ class SkiaPerfDestination extends MetricDestination {
|
||||
// 1st, create a map based on git repo, git revision, and point id. Git repo
|
||||
// and git revision are the top level components of the Skia perf GCS object
|
||||
// name.
|
||||
final Map<String, Map<String, Map<String, SkiaPerfPoint>>> pointMap =
|
||||
final Map<String, Map<String?, Map<String, SkiaPerfPoint>>> pointMap =
|
||||
<String, Map<String, Map<String, SkiaPerfPoint>>>{};
|
||||
for (final SkiaPerfPoint p
|
||||
in points.map((MetricPoint x) => SkiaPerfPoint.fromPoint(x))) {
|
||||
if (p != null) {
|
||||
pointMap[p.githubRepo] ??= <String, Map<String, SkiaPerfPoint>>{};
|
||||
pointMap[p.githubRepo][p.gitHash] ??= <String, SkiaPerfPoint>{};
|
||||
pointMap[p.githubRepo][p.gitHash][p.id] = p;
|
||||
pointMap[p.githubRepo]![p.gitHash] ??= <String, SkiaPerfPoint>{};
|
||||
pointMap[p.githubRepo]![p.gitHash]![p.id] = p;
|
||||
}
|
||||
}
|
||||
|
||||
// 2nd, read existing points from the gcs object and update with new ones.
|
||||
for (final String repo in pointMap.keys) {
|
||||
for (final String revision in pointMap[repo].keys) {
|
||||
for (final String? revision in pointMap[repo]!.keys) {
|
||||
final String objectName = await SkiaPerfGcsAdaptor.computeObjectName(
|
||||
repo, revision, commitTime);
|
||||
final Map<String, SkiaPerfPoint> newPoints = pointMap[repo][revision];
|
||||
final Map<String, SkiaPerfPoint>? newPoints = pointMap[repo]![revision];
|
||||
// If too many bots are writing the metrics of a git revision into this
|
||||
// single json file (with name `objectName`), the contention on the lock
|
||||
// might be too high. In that case, break the json file into multiple
|
||||
// json files according to bot names or task names. Skia perf read all
|
||||
// json files in the directory so one can use arbitrary names for those
|
||||
// sharded json file names.
|
||||
_lock.protectedRun('$objectName.lock', () async {
|
||||
_lock!.protectedRun('$objectName.lock', () async {
|
||||
final List<SkiaPerfPoint> oldPoints =
|
||||
await _gcs.readPoints(objectName);
|
||||
for (final SkiaPerfPoint p in oldPoints) {
|
||||
if (newPoints[p.id] == null) {
|
||||
if (newPoints![p.id] == null) {
|
||||
newPoints[p.id] = p;
|
||||
}
|
||||
}
|
||||
await _gcs.writePoints(objectName, newPoints.values.toList());
|
||||
await _gcs.writePoints(objectName, newPoints!.values.toList());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final SkiaPerfGcsAdaptor _gcs;
|
||||
final GcsLock _lock;
|
||||
late final GcsLock? _lock;
|
||||
}
|
||||
|
@ -1,23 +1,24 @@
|
||||
name: metrics_center
|
||||
version: 0.1.1
|
||||
version: 1.0.0
|
||||
description:
|
||||
Support multiple performance metrics sources/formats and destinations.
|
||||
repository: https://github.com/flutter/packages/tree/master/packages/metrics_center
|
||||
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+metrics_center%22
|
||||
|
||||
environment:
|
||||
sdk: '>=2.10.0 <3.0.0'
|
||||
sdk: '>=2.12.0 <3.0.0'
|
||||
|
||||
dependencies:
|
||||
crypto: ^3.0.0
|
||||
equatable: ^1.2.5
|
||||
gcloud: ^0.8.0
|
||||
crypto: ^3.0.1
|
||||
equatable: ^2.0.3
|
||||
gcloud: ^0.8.2
|
||||
googleapis: ^3.0.0
|
||||
googleapis_auth: ^1.0.0
|
||||
googleapis_auth: ^1.1.0
|
||||
http: ^0.13.3
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: ^2.1.1
|
||||
fake_async: ^1.2.0
|
||||
mockito: ^5.0.0
|
||||
pedantic: ^1.10.0
|
||||
test: ^1.17.0
|
||||
mockito: ^5.0.14
|
||||
pedantic: ^1.11.1
|
||||
test: ^1.17.11
|
||||
|
@ -38,11 +38,11 @@ void main() {
|
||||
expect(detailedPoint.tags[kUnitKey], equals('ns'));
|
||||
});
|
||||
|
||||
final Map<String, dynamic> credentialsJson = getTestGcpCredentialsJson();
|
||||
final Map<String, dynamic>? credentialsJson = getTestGcpCredentialsJson();
|
||||
|
||||
test('FlutterDestination integration test with update.', () async {
|
||||
final FlutterDestination dst =
|
||||
await FlutterDestination.makeFromCredentialsJson(credentialsJson,
|
||||
await FlutterDestination.makeFromCredentialsJson(credentialsJson!,
|
||||
isTesting: true);
|
||||
dst.update(<FlutterEngineMetricPoint>[simplePoint],
|
||||
DateTime.fromMillisecondsSinceEpoch(123));
|
||||
|
@ -10,9 +10,11 @@ import 'package:googleapis/storage/v1.dart';
|
||||
import 'package:googleapis_auth/auth_io.dart';
|
||||
import 'package:metrics_center/src/constants.dart';
|
||||
import 'package:metrics_center/src/gcs_lock.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'common.dart';
|
||||
import 'gcs_lock_test.mocks.dart';
|
||||
import 'utility.dart';
|
||||
|
||||
enum TestPhase {
|
||||
@ -20,11 +22,10 @@ enum TestPhase {
|
||||
run2,
|
||||
}
|
||||
|
||||
class MockClient extends Mock implements AuthClient {}
|
||||
|
||||
@GenerateMocks(<Type>[AuthClient])
|
||||
void main() {
|
||||
const Duration kDelayStep = Duration(milliseconds: 10);
|
||||
final Map<String, dynamic> credentialsJson = getTestGcpCredentialsJson();
|
||||
final Map<String, dynamic>? credentialsJson = getTestGcpCredentialsJson();
|
||||
|
||||
test('GcsLock prints warnings for long waits', () {
|
||||
// Capture print to verify error messages.
|
||||
@ -34,7 +35,7 @@ void main() {
|
||||
|
||||
Zone.current.fork(specification: spec).run<void>(() {
|
||||
fakeAsync((FakeAsync fakeAsync) {
|
||||
final MockClient mockClient = MockClient();
|
||||
final MockAuthClient mockClient = MockAuthClient();
|
||||
final GcsLock lock = GcsLock(mockClient, 'mockBucket');
|
||||
when(mockClient.send(any)).thenThrow(DetailedApiRequestError(412, ''));
|
||||
final Future<void> runFinished =
|
||||
|
117
packages/metrics_center/test/gcs_lock_test.mocks.dart
Normal file
117
packages/metrics_center/test/gcs_lock_test.mocks.dart
Normal file
@ -0,0 +1,117 @@
|
||||
// Mocks generated by Mockito 5.0.14 from annotations
|
||||
// in metrics_center/test/gcs_lock_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
import 'dart:async' as _i5;
|
||||
import 'dart:convert' as _i6;
|
||||
import 'dart:typed_data' as _i7;
|
||||
|
||||
import 'package:googleapis_auth/src/access_credentials.dart' as _i2;
|
||||
import 'package:googleapis_auth/src/auth_client.dart' as _i4;
|
||||
import 'package:http/http.dart' as _i3;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
|
||||
// ignore_for_file: always_specify_types
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_overrides
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
|
||||
class _FakeAccessCredentials_0 extends _i1.Fake
|
||||
implements _i2.AccessCredentials {}
|
||||
|
||||
class _FakeResponse_1 extends _i1.Fake implements _i3.Response {}
|
||||
|
||||
class _FakeStreamedResponse_2 extends _i1.Fake implements _i3.StreamedResponse {
|
||||
}
|
||||
|
||||
/// A class which mocks [AuthClient].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockAuthClient extends _i1.Mock implements _i4.AuthClient {
|
||||
MockAuthClient() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
_i2.AccessCredentials get credentials =>
|
||||
(super.noSuchMethod(Invocation.getter(#credentials),
|
||||
returnValue: _FakeAccessCredentials_0()) as _i2.AccessCredentials);
|
||||
@override
|
||||
String toString() => super.toString();
|
||||
@override
|
||||
_i5.Future<_i3.Response> head(Uri? url, {Map<String, String>? headers}) =>
|
||||
(super.noSuchMethod(Invocation.method(#head, [url], {#headers: headers}),
|
||||
returnValue: Future<_i3.Response>.value(_FakeResponse_1()))
|
||||
as _i5.Future<_i3.Response>);
|
||||
@override
|
||||
_i5.Future<_i3.Response> get(Uri? url, {Map<String, String>? headers}) =>
|
||||
(super.noSuchMethod(Invocation.method(#get, [url], {#headers: headers}),
|
||||
returnValue: Future<_i3.Response>.value(_FakeResponse_1()))
|
||||
as _i5.Future<_i3.Response>);
|
||||
@override
|
||||
_i5.Future<_i3.Response> post(Uri? url,
|
||||
{Map<String, String>? headers,
|
||||
Object? body,
|
||||
_i6.Encoding? encoding}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#post, [url],
|
||||
{#headers: headers, #body: body, #encoding: encoding}),
|
||||
returnValue: Future<_i3.Response>.value(_FakeResponse_1()))
|
||||
as _i5.Future<_i3.Response>);
|
||||
@override
|
||||
_i5.Future<_i3.Response> put(Uri? url,
|
||||
{Map<String, String>? headers,
|
||||
Object? body,
|
||||
_i6.Encoding? encoding}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#put, [url],
|
||||
{#headers: headers, #body: body, #encoding: encoding}),
|
||||
returnValue: Future<_i3.Response>.value(_FakeResponse_1()))
|
||||
as _i5.Future<_i3.Response>);
|
||||
@override
|
||||
_i5.Future<_i3.Response> patch(Uri? url,
|
||||
{Map<String, String>? headers,
|
||||
Object? body,
|
||||
_i6.Encoding? encoding}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#patch, [url],
|
||||
{#headers: headers, #body: body, #encoding: encoding}),
|
||||
returnValue: Future<_i3.Response>.value(_FakeResponse_1()))
|
||||
as _i5.Future<_i3.Response>);
|
||||
@override
|
||||
_i5.Future<_i3.Response> delete(Uri? url,
|
||||
{Map<String, String>? headers,
|
||||
Object? body,
|
||||
_i6.Encoding? encoding}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#delete, [url],
|
||||
{#headers: headers, #body: body, #encoding: encoding}),
|
||||
returnValue: Future<_i3.Response>.value(_FakeResponse_1()))
|
||||
as _i5.Future<_i3.Response>);
|
||||
@override
|
||||
_i5.Future<String> read(Uri? url, {Map<String, String>? headers}) =>
|
||||
(super.noSuchMethod(Invocation.method(#read, [url], {#headers: headers}),
|
||||
returnValue: Future<String>.value('')) as _i5.Future<String>);
|
||||
@override
|
||||
_i5.Future<_i7.Uint8List> readBytes(Uri? url,
|
||||
{Map<String, String>? headers}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#readBytes, [url], {#headers: headers}),
|
||||
returnValue: Future<_i7.Uint8List>.value(_i7.Uint8List(0)))
|
||||
as _i5.Future<_i7.Uint8List>);
|
||||
@override
|
||||
_i5.Future<_i3.StreamedResponse> send(_i3.BaseRequest? request) =>
|
||||
(super.noSuchMethod(Invocation.method(#send, [request]),
|
||||
returnValue:
|
||||
Future<_i3.StreamedResponse>.value(_FakeStreamedResponse_2()))
|
||||
as _i5.Future<_i3.StreamedResponse>);
|
||||
@override
|
||||
void close() => super.noSuchMethod(Invocation.method(#close, []),
|
||||
returnValueForMissingStub: null);
|
||||
}
|
@ -12,15 +12,13 @@ import 'package:googleapis_auth/auth_io.dart';
|
||||
import 'package:metrics_center/metrics_center.dart';
|
||||
import 'package:metrics_center/src/constants.dart';
|
||||
import 'package:metrics_center/src/gcs_lock.dart';
|
||||
import 'package:mockito/annotations.dart';
|
||||
import 'package:mockito/mockito.dart';
|
||||
|
||||
import 'common.dart';
|
||||
import 'skiaperf_test.mocks.dart';
|
||||
import 'utility.dart';
|
||||
|
||||
class MockBucket extends Mock implements Bucket {}
|
||||
|
||||
class MockObjectInfo extends Mock implements ObjectInfo {}
|
||||
|
||||
class MockGcsLock implements GcsLock {
|
||||
@override
|
||||
Future<void> protectedRun(
|
||||
@ -46,6 +44,7 @@ class MockSkiaPerfGcsAdaptor implements SkiaPerfGcsAdaptor {
|
||||
<String, List<SkiaPerfPoint>>{};
|
||||
}
|
||||
|
||||
@GenerateMocks(<Type>[Bucket, ObjectInfo])
|
||||
Future<void> main() async {
|
||||
const double kValue1 = 1.0;
|
||||
const double kValue2 = 2.0;
|
||||
@ -353,6 +352,8 @@ Future<void> main() async {
|
||||
];
|
||||
final String skiaPerfJson =
|
||||
jsonEncode(SkiaPerfPoint.toSkiaPerfJson(writePoints));
|
||||
when(testBucket.writeBytes(testObjectName, utf8.encode(skiaPerfJson)))
|
||||
.thenAnswer((_) async => FakeObjectInfo());
|
||||
await skiaPerfGcs.writePoints(testObjectName, writePoints);
|
||||
verify(testBucket.writeBytes(testObjectName, utf8.encode(skiaPerfJson)));
|
||||
|
||||
@ -392,9 +393,9 @@ Future<void> main() async {
|
||||
});
|
||||
|
||||
// The following is for integration tests.
|
||||
Bucket testBucket;
|
||||
GcsLock testLock;
|
||||
final Map<String, dynamic> credentialsJson = getTestGcpCredentialsJson();
|
||||
Bucket? testBucket;
|
||||
GcsLock? testLock;
|
||||
final Map<String, dynamic>? credentialsJson = getTestGcpCredentialsJson();
|
||||
if (credentialsJson != null) {
|
||||
final ServiceAccountCredentials credentials =
|
||||
ServiceAccountCredentials.fromJson(credentialsJson);
|
||||
@ -412,7 +413,7 @@ Future<void> main() async {
|
||||
}
|
||||
|
||||
Future<void> skiaPerfGcsAdapterIntegrationTest() async {
|
||||
final SkiaPerfGcsAdaptor skiaPerfGcs = SkiaPerfGcsAdaptor(testBucket);
|
||||
final SkiaPerfGcsAdaptor skiaPerfGcs = SkiaPerfGcsAdaptor(testBucket!);
|
||||
|
||||
final String testObjectName = await SkiaPerfGcsAdaptor.computeObjectName(
|
||||
kFlutterFrameworkRepo,
|
||||
@ -443,7 +444,7 @@ Future<void> main() async {
|
||||
}
|
||||
|
||||
Future<void> skiaPerfGcsIntegrationTestWithEnginePoints() async {
|
||||
final SkiaPerfGcsAdaptor skiaPerfGcs = SkiaPerfGcsAdaptor(testBucket);
|
||||
final SkiaPerfGcsAdaptor skiaPerfGcs = SkiaPerfGcsAdaptor(testBucket!);
|
||||
|
||||
final String testObjectName = await SkiaPerfGcsAdaptor.computeObjectName(
|
||||
kFlutterEngineRepo,
|
||||
@ -569,7 +570,7 @@ Future<void> main() async {
|
||||
|
||||
Future<void> skiaPerfDestinationIntegrationTest() async {
|
||||
final SkiaPerfDestination destination =
|
||||
SkiaPerfDestination(SkiaPerfGcsAdaptor(testBucket), testLock);
|
||||
SkiaPerfDestination(SkiaPerfGcsAdaptor(testBucket!), testLock);
|
||||
await destination.update(<MetricPoint>[cocoonPointRev1Metric1],
|
||||
DateTime.fromMillisecondsSinceEpoch(123));
|
||||
}
|
||||
@ -580,3 +581,32 @@ Future<void> main() async {
|
||||
skip: testBucket == null,
|
||||
);
|
||||
}
|
||||
|
||||
class FakeObjectInfo extends ObjectInfo {
|
||||
@override
|
||||
int get crc32CChecksum => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
Uri get downloadLink => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
String get etag => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
ObjectGeneration get generation => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
int get length => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
List<int> get md5Hash => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
ObjectMetadata get metadata => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
String get name => throw UnimplementedError();
|
||||
|
||||
@override
|
||||
DateTime get updated => throw UnimplementedError();
|
||||
}
|
||||
|
175
packages/metrics_center/test/skiaperf_test.mocks.dart
Normal file
175
packages/metrics_center/test/skiaperf_test.mocks.dart
Normal file
@ -0,0 +1,175 @@
|
||||
// Mocks generated by Mockito 5.0.14 from annotations
|
||||
// in metrics_center/test/skiaperf_test.dart.
|
||||
// Do not manually edit this file.
|
||||
|
||||
import 'dart:async' as _i2;
|
||||
|
||||
import 'package:gcloud/common.dart' as _i4;
|
||||
import 'package:gcloud/storage.dart' as _i3;
|
||||
import 'package:mockito/mockito.dart' as _i1;
|
||||
|
||||
// ignore_for_file: always_specify_types
|
||||
// ignore_for_file: avoid_redundant_argument_values
|
||||
// ignore_for_file: avoid_setters_without_getters
|
||||
// ignore_for_file: camel_case_types
|
||||
// ignore_for_file: comment_references
|
||||
// ignore_for_file: implementation_imports
|
||||
// ignore_for_file: invalid_use_of_visible_for_testing_member
|
||||
// ignore_for_file: prefer_const_constructors
|
||||
// ignore_for_file: unnecessary_overrides
|
||||
// ignore_for_file: unnecessary_parenthesis
|
||||
|
||||
class _FakeStreamSink_0<S> extends _i1.Fake implements _i2.StreamSink<S> {}
|
||||
|
||||
class _FakeObjectInfo_1 extends _i1.Fake implements _i3.ObjectInfo {}
|
||||
|
||||
class _FakePage_2<T> extends _i1.Fake implements _i4.Page<T> {}
|
||||
|
||||
class _FakeDateTime_3 extends _i1.Fake implements DateTime {}
|
||||
|
||||
class _FakeUri_4 extends _i1.Fake implements Uri {}
|
||||
|
||||
class _FakeObjectGeneration_5 extends _i1.Fake implements _i3.ObjectGeneration {
|
||||
}
|
||||
|
||||
class _FakeObjectMetadata_6 extends _i1.Fake implements _i3.ObjectMetadata {}
|
||||
|
||||
/// A class which mocks [Bucket].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockBucket extends _i1.Mock implements _i3.Bucket {
|
||||
MockBucket() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
String get bucketName =>
|
||||
(super.noSuchMethod(Invocation.getter(#bucketName), returnValue: '')
|
||||
as String);
|
||||
@override
|
||||
String absoluteObjectName(String? objectName) =>
|
||||
(super.noSuchMethod(Invocation.method(#absoluteObjectName, [objectName]),
|
||||
returnValue: '') as String);
|
||||
@override
|
||||
_i2.StreamSink<List<int>> write(String? objectName,
|
||||
{int? length,
|
||||
_i3.ObjectMetadata? metadata,
|
||||
_i3.Acl? acl,
|
||||
_i3.PredefinedAcl? predefinedAcl,
|
||||
String? contentType}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#write, [
|
||||
objectName
|
||||
], {
|
||||
#length: length,
|
||||
#metadata: metadata,
|
||||
#acl: acl,
|
||||
#predefinedAcl: predefinedAcl,
|
||||
#contentType: contentType
|
||||
}),
|
||||
returnValue: _FakeStreamSink_0<List<int>>())
|
||||
as _i2.StreamSink<List<int>>);
|
||||
@override
|
||||
_i2.Future<_i3.ObjectInfo> writeBytes(String? name, List<int>? bytes,
|
||||
{_i3.ObjectMetadata? metadata,
|
||||
_i3.Acl? acl,
|
||||
_i3.PredefinedAcl? predefinedAcl,
|
||||
String? contentType}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#writeBytes, [
|
||||
name,
|
||||
bytes
|
||||
], {
|
||||
#metadata: metadata,
|
||||
#acl: acl,
|
||||
#predefinedAcl: predefinedAcl,
|
||||
#contentType: contentType
|
||||
}),
|
||||
returnValue: Future<_i3.ObjectInfo>.value(_FakeObjectInfo_1()))
|
||||
as _i2.Future<_i3.ObjectInfo>);
|
||||
@override
|
||||
_i2.Stream<List<int>> read(String? objectName, {int? offset, int? length}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#read, [objectName], {#offset: offset, #length: length}),
|
||||
returnValue: Stream<List<int>>.empty()) as _i2.Stream<List<int>>);
|
||||
@override
|
||||
_i2.Future<_i3.ObjectInfo> info(String? name) =>
|
||||
(super.noSuchMethod(Invocation.method(#info, [name]),
|
||||
returnValue: Future<_i3.ObjectInfo>.value(_FakeObjectInfo_1()))
|
||||
as _i2.Future<_i3.ObjectInfo>);
|
||||
@override
|
||||
_i2.Future<dynamic> delete(String? name) =>
|
||||
(super.noSuchMethod(Invocation.method(#delete, [name]),
|
||||
returnValue: Future<dynamic>.value()) as _i2.Future<dynamic>);
|
||||
@override
|
||||
_i2.Future<dynamic> updateMetadata(
|
||||
String? objectName, _i3.ObjectMetadata? metadata) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#updateMetadata, [objectName, metadata]),
|
||||
returnValue: Future<dynamic>.value()) as _i2.Future<dynamic>);
|
||||
@override
|
||||
_i2.Stream<_i3.BucketEntry> list({String? prefix, String? delimiter}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(
|
||||
#list, [], {#prefix: prefix, #delimiter: delimiter}),
|
||||
returnValue: Stream<_i3.BucketEntry>.empty())
|
||||
as _i2.Stream<_i3.BucketEntry>);
|
||||
@override
|
||||
_i2.Future<_i4.Page<_i3.BucketEntry>> page(
|
||||
{String? prefix, String? delimiter, int? pageSize = 50}) =>
|
||||
(super.noSuchMethod(
|
||||
Invocation.method(#page, [], {
|
||||
#prefix: prefix,
|
||||
#delimiter: delimiter,
|
||||
#pageSize: pageSize
|
||||
}),
|
||||
returnValue: Future<_i4.Page<_i3.BucketEntry>>.value(
|
||||
_FakePage_2<_i3.BucketEntry>()))
|
||||
as _i2.Future<_i4.Page<_i3.BucketEntry>>);
|
||||
@override
|
||||
String toString() => super.toString();
|
||||
}
|
||||
|
||||
/// A class which mocks [ObjectInfo].
|
||||
///
|
||||
/// See the documentation for Mockito's code generation for more information.
|
||||
class MockObjectInfo extends _i1.Mock implements _i3.ObjectInfo {
|
||||
MockObjectInfo() {
|
||||
_i1.throwOnMissingStub(this);
|
||||
}
|
||||
|
||||
@override
|
||||
String get name =>
|
||||
(super.noSuchMethod(Invocation.getter(#name), returnValue: '') as String);
|
||||
@override
|
||||
int get length =>
|
||||
(super.noSuchMethod(Invocation.getter(#length), returnValue: 0) as int);
|
||||
@override
|
||||
DateTime get updated => (super.noSuchMethod(Invocation.getter(#updated),
|
||||
returnValue: _FakeDateTime_3()) as DateTime);
|
||||
@override
|
||||
String get etag =>
|
||||
(super.noSuchMethod(Invocation.getter(#etag), returnValue: '') as String);
|
||||
@override
|
||||
List<int> get md5Hash =>
|
||||
(super.noSuchMethod(Invocation.getter(#md5Hash), returnValue: <int>[])
|
||||
as List<int>);
|
||||
@override
|
||||
int get crc32CChecksum =>
|
||||
(super.noSuchMethod(Invocation.getter(#crc32CChecksum), returnValue: 0)
|
||||
as int);
|
||||
@override
|
||||
Uri get downloadLink => (super.noSuchMethod(Invocation.getter(#downloadLink),
|
||||
returnValue: _FakeUri_4()) as Uri);
|
||||
@override
|
||||
_i3.ObjectGeneration get generation =>
|
||||
(super.noSuchMethod(Invocation.getter(#generation),
|
||||
returnValue: _FakeObjectGeneration_5()) as _i3.ObjectGeneration);
|
||||
@override
|
||||
_i3.ObjectMetadata get metadata =>
|
||||
(super.noSuchMethod(Invocation.getter(#metadata),
|
||||
returnValue: _FakeObjectMetadata_6()) as _i3.ObjectMetadata);
|
||||
@override
|
||||
String toString() => super.toString();
|
||||
}
|
@ -13,11 +13,11 @@ void expectSetMatch<T>(Iterable<T> actual, Iterable<T> expected) {
|
||||
}
|
||||
|
||||
// May return null if the credentials file doesn't exist.
|
||||
Map<String, dynamic> getTestGcpCredentialsJson() {
|
||||
Map<String, dynamic>? getTestGcpCredentialsJson() {
|
||||
final File f = File('secret/test_gcp_credentials.json');
|
||||
if (!f.existsSync()) {
|
||||
return null;
|
||||
}
|
||||
return jsonDecode(File('secret/test_gcp_credentials.json').readAsStringSync())
|
||||
as Map<String, dynamic>;
|
||||
as Map<String, dynamic>?;
|
||||
}
|
||||
|
Reference in New Issue
Block a user