diff --git a/packages/metrics_center/CHANGELOG.md b/packages/metrics_center/CHANGELOG.md index 7fcef0fead..731d2ce8ea 100644 --- a/packages/metrics_center/CHANGELOG.md +++ b/packages/metrics_center/CHANGELOG.md @@ -1,3 +1,7 @@ +# 1.0.0 + +- Null safety support + # 0.1.1 - Update packages to null safe diff --git a/packages/metrics_center/lib/src/common.dart b/packages/metrics_center/lib/src/common.dart index fe98ff90e0..ca6cabddc7 100644 --- a/packages/metrics_center/lib/src/common.dart +++ b/packages/metrics_center/lib/src/common.dart @@ -16,11 +16,11 @@ class MetricPoint extends Equatable { /// Creates a new data point. MetricPoint( this.value, - Map tags, + Map tags, ) : _tags = SplayTreeMap.from(tags); /// Can store integer values. - final double value; + final double? value; /// Test name, unit, timestamp, configs, git revision, ..., in sorted order. UnmodifiableMapView get tags => @@ -43,7 +43,7 @@ class MetricPoint extends Equatable { final SplayTreeMap _tags; @override - List get props => [value, tags]; + List get props => [value, tags]; } /// Interface to write [MetricPoint]. diff --git a/packages/metrics_center/lib/src/gcs_lock.dart b/packages/metrics_center/lib/src/gcs_lock.dart index c8ebe930f7..ca64f648c3 100644 --- a/packages/metrics_center/lib/src/gcs_lock.dart +++ b/packages/metrics_center/lib/src/gcs_lock.dart @@ -82,7 +82,7 @@ class GcsLock { await _api.objects.delete(_bucketName, lockFileName); } - StorageApi _api; + late StorageApi _api; final String _bucketName; final AuthClient _client; diff --git a/packages/metrics_center/lib/src/google_benchmark.dart b/packages/metrics_center/lib/src/google_benchmark.dart index 118167f628..bbb567dcf2 100644 --- a/packages/metrics_center/lib/src/google_benchmark.dart +++ b/packages/metrics_center/lib/src/google_benchmark.dart @@ -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, - {kNameKey: name, kSubResultKey: subResult} + {kNameKey: name, kSubResultKey: subResult} ..addAll(context) ..addAll( subResult.endsWith('time') ? timeUnitMap : {}), diff --git a/packages/metrics_center/lib/src/skiaperf.dart b/packages/metrics_center/lib/src/skiaperf.dart index 063bad1d33..999b73481b 100644 --- a/packages/metrics_center/lib/src/skiaperf.dart +++ b/packages/metrics_center/lib/src/skiaperf.dart @@ -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, - {} + {} ..addAll(_options) - ..addAll({ + ..addAll({ 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 _toSubResultJson() { return { @@ -260,7 +260,7 @@ class SkiaPerfGcsAdaptor { } Future> _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 results = decodedJson[kSkiaPerfResultsKey] as Map; 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) .cast(), 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 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 _gcsNameToGithubRepo = {}; + static final Map _gcsNameToGithubRepo = {}; 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>> pointMap = + final Map>> pointMap = >>{}; for (final SkiaPerfPoint p in points.map((MetricPoint x) => SkiaPerfPoint.fromPoint(x))) { if (p != null) { pointMap[p.githubRepo] ??= >{}; - pointMap[p.githubRepo][p.gitHash] ??= {}; - pointMap[p.githubRepo][p.gitHash][p.id] = p; + pointMap[p.githubRepo]![p.gitHash] ??= {}; + 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 newPoints = pointMap[repo][revision]; + final Map? 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 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; } diff --git a/packages/metrics_center/pubspec.yaml b/packages/metrics_center/pubspec.yaml index 39218d3e45..3c7947c996 100644 --- a/packages/metrics_center/pubspec.yaml +++ b/packages/metrics_center/pubspec.yaml @@ -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 diff --git a/packages/metrics_center/test/flutter_test.dart b/packages/metrics_center/test/flutter_test.dart index 63b6e945a5..d50794d45b 100644 --- a/packages/metrics_center/test/flutter_test.dart +++ b/packages/metrics_center/test/flutter_test.dart @@ -38,11 +38,11 @@ void main() { expect(detailedPoint.tags[kUnitKey], equals('ns')); }); - final Map credentialsJson = getTestGcpCredentialsJson(); + final Map? credentialsJson = getTestGcpCredentialsJson(); test('FlutterDestination integration test with update.', () async { final FlutterDestination dst = - await FlutterDestination.makeFromCredentialsJson(credentialsJson, + await FlutterDestination.makeFromCredentialsJson(credentialsJson!, isTesting: true); dst.update([simplePoint], DateTime.fromMillisecondsSinceEpoch(123)); diff --git a/packages/metrics_center/test/gcs_lock_test.dart b/packages/metrics_center/test/gcs_lock_test.dart index 6e9c1e9a9c..b5228bf8f0 100644 --- a/packages/metrics_center/test/gcs_lock_test.dart +++ b/packages/metrics_center/test/gcs_lock_test.dart @@ -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([AuthClient]) void main() { const Duration kDelayStep = Duration(milliseconds: 10); - final Map credentialsJson = getTestGcpCredentialsJson(); + final Map? 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(() { 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 runFinished = diff --git a/packages/metrics_center/test/gcs_lock_test.mocks.dart b/packages/metrics_center/test/gcs_lock_test.mocks.dart new file mode 100644 index 0000000000..58b95a791e --- /dev/null +++ b/packages/metrics_center/test/gcs_lock_test.mocks.dart @@ -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? 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? 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? 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? 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? 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? 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 read(Uri? url, {Map? headers}) => + (super.noSuchMethod(Invocation.method(#read, [url], {#headers: headers}), + returnValue: Future.value('')) as _i5.Future); + @override + _i5.Future<_i7.Uint8List> readBytes(Uri? url, + {Map? 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); +} diff --git a/packages/metrics_center/test/skiaperf_test.dart b/packages/metrics_center/test/skiaperf_test.dart index dcfedf068a..09eeed91eb 100644 --- a/packages/metrics_center/test/skiaperf_test.dart +++ b/packages/metrics_center/test/skiaperf_test.dart @@ -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 protectedRun( @@ -46,6 +44,7 @@ class MockSkiaPerfGcsAdaptor implements SkiaPerfGcsAdaptor { >{}; } +@GenerateMocks([Bucket, ObjectInfo]) Future main() async { const double kValue1 = 1.0; const double kValue2 = 2.0; @@ -353,6 +352,8 @@ Future 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 main() async { }); // The following is for integration tests. - Bucket testBucket; - GcsLock testLock; - final Map credentialsJson = getTestGcpCredentialsJson(); + Bucket? testBucket; + GcsLock? testLock; + final Map? credentialsJson = getTestGcpCredentialsJson(); if (credentialsJson != null) { final ServiceAccountCredentials credentials = ServiceAccountCredentials.fromJson(credentialsJson); @@ -412,7 +413,7 @@ Future main() async { } Future skiaPerfGcsAdapterIntegrationTest() async { - final SkiaPerfGcsAdaptor skiaPerfGcs = SkiaPerfGcsAdaptor(testBucket); + final SkiaPerfGcsAdaptor skiaPerfGcs = SkiaPerfGcsAdaptor(testBucket!); final String testObjectName = await SkiaPerfGcsAdaptor.computeObjectName( kFlutterFrameworkRepo, @@ -443,7 +444,7 @@ Future main() async { } Future skiaPerfGcsIntegrationTestWithEnginePoints() async { - final SkiaPerfGcsAdaptor skiaPerfGcs = SkiaPerfGcsAdaptor(testBucket); + final SkiaPerfGcsAdaptor skiaPerfGcs = SkiaPerfGcsAdaptor(testBucket!); final String testObjectName = await SkiaPerfGcsAdaptor.computeObjectName( kFlutterEngineRepo, @@ -569,7 +570,7 @@ Future main() async { Future skiaPerfDestinationIntegrationTest() async { final SkiaPerfDestination destination = - SkiaPerfDestination(SkiaPerfGcsAdaptor(testBucket), testLock); + SkiaPerfDestination(SkiaPerfGcsAdaptor(testBucket!), testLock); await destination.update([cocoonPointRev1Metric1], DateTime.fromMillisecondsSinceEpoch(123)); } @@ -580,3 +581,32 @@ Future 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 get md5Hash => throw UnimplementedError(); + + @override + ObjectMetadata get metadata => throw UnimplementedError(); + + @override + String get name => throw UnimplementedError(); + + @override + DateTime get updated => throw UnimplementedError(); +} diff --git a/packages/metrics_center/test/skiaperf_test.mocks.dart b/packages/metrics_center/test/skiaperf_test.mocks.dart new file mode 100644 index 0000000000..515f8833fd --- /dev/null +++ b/packages/metrics_center/test/skiaperf_test.mocks.dart @@ -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 extends _i1.Fake implements _i2.StreamSink {} + +class _FakeObjectInfo_1 extends _i1.Fake implements _i3.ObjectInfo {} + +class _FakePage_2 extends _i1.Fake implements _i4.Page {} + +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> 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>()) + as _i2.StreamSink>); + @override + _i2.Future<_i3.ObjectInfo> writeBytes(String? name, List? 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> read(String? objectName, {int? offset, int? length}) => + (super.noSuchMethod( + Invocation.method( + #read, [objectName], {#offset: offset, #length: length}), + returnValue: Stream>.empty()) as _i2.Stream>); + @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 delete(String? name) => + (super.noSuchMethod(Invocation.method(#delete, [name]), + returnValue: Future.value()) as _i2.Future); + @override + _i2.Future updateMetadata( + String? objectName, _i3.ObjectMetadata? metadata) => + (super.noSuchMethod( + Invocation.method(#updateMetadata, [objectName, metadata]), + returnValue: Future.value()) as _i2.Future); + @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 get md5Hash => + (super.noSuchMethod(Invocation.getter(#md5Hash), returnValue: []) + as List); + @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(); +} diff --git a/packages/metrics_center/test/utility.dart b/packages/metrics_center/test/utility.dart index 31808a5730..f0c8e07894 100644 --- a/packages/metrics_center/test/utility.dart +++ b/packages/metrics_center/test/utility.dart @@ -13,11 +13,11 @@ void expectSetMatch(Iterable actual, Iterable expected) { } // May return null if the credentials file doesn't exist. -Map getTestGcpCredentialsJson() { +Map? 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; + as Map?; }