From 784ebc178e06a7f6c7fc2930c744eec0fd2634c1 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Mon, 22 Apr 2019 15:07:28 -0700 Subject: [PATCH 01/13] Performance rewrite dart side --- .../example/lib/main.dart | 2 +- .../lib/firebase_performance.dart | 1 - .../lib/src/firebase_performance.dart | 62 ++++----- .../lib/src/http_metric.dart | 71 ++--------- .../lib/src/performance_attributes.dart | 39 +++--- .../firebase_performance/lib/src/trace.dart | 118 ++++++------------ 6 files changed, 103 insertions(+), 190 deletions(-) diff --git a/packages/firebase_performance/example/lib/main.dart b/packages/firebase_performance/example/lib/main.dart index b9c46614748b..d81e951faaf0 100644 --- a/packages/firebase_performance/example/lib/main.dart +++ b/packages/firebase_performance/example/lib/main.dart @@ -77,7 +77,7 @@ class _MyAppState extends State { }); final Trace trace = _performance.newTrace("test"); - trace.incrementCounter("counter1", 16); + trace.putMetric("counter1", 16); trace.putAttribute("favorite_color", "blue"); await trace.start(); diff --git a/packages/firebase_performance/lib/firebase_performance.dart b/packages/firebase_performance/lib/firebase_performance.dart index 17dbcfc07863..8f8a2e7a4348 100644 --- a/packages/firebase_performance/lib/firebase_performance.dart +++ b/packages/firebase_performance/lib/firebase_performance.dart @@ -5,7 +5,6 @@ library firebase_performance; import 'dart:async'; -import 'dart:collection'; import 'package:flutter/services.dart'; import 'package:flutter/foundation.dart'; diff --git a/packages/firebase_performance/lib/src/firebase_performance.dart b/packages/firebase_performance/lib/src/firebase_performance.dart index 381236d44dc7..165ed0851f87 100644 --- a/packages/firebase_performance/lib/src/firebase_performance.dart +++ b/packages/firebase_performance/lib/src/firebase_performance.dart @@ -13,9 +13,6 @@ enum HttpMethod { Connect, Delete, Get, Head, Options, Patch, Post, Put, Trace } class FirebasePerformance { FirebasePerformance._(); - static int _traceCount = 0; - static int _httpMetricCount = 0; - @visibleForTesting static const MethodChannel channel = MethodChannel('plugins.flutter.io/firebase_performance'); @@ -23,30 +20,28 @@ class FirebasePerformance { /// Singleton of [FirebasePerformance]. static final FirebasePerformance instance = FirebasePerformance._(); + static int _channelCount = 0; + /// Determines whether performance monitoring is enabled or disabled. /// /// True if performance monitoring is enabled and false if performance /// monitoring is disabled. This is for dynamic enable/disable state. This /// does not reflect whether instrumentation is enabled/disabled. - Future isPerformanceCollectionEnabled() async { - final bool isEnabled = await channel - // TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter. - // https://github.com/flutter/flutter/issues/26431 - // ignore: strong_mode_implicit_dynamic_method - .invokeMethod('FirebasePerformance#isPerformanceCollectionEnabled'); - return isEnabled; + Future isPerformanceCollectionEnabled() { + return channel.invokeMethod( + 'FirebasePerformance#isPerformanceCollectionEnabled', + ); } - /// Enables or disables performance monitoring. + /// Enables or disables performance monitoring asynchronously. /// /// This setting is persisted and applied on future invocations of your /// application. By default, performance monitoring is enabled. Future setPerformanceCollectionEnabled(bool enable) async { - // TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter. - // https://github.com/flutter/flutter/issues/26431 - // ignore: strong_mode_implicit_dynamic_method - await channel.invokeMethod( - 'FirebasePerformance#setPerformanceCollectionEnabled', enable); + return channel.invokeMethod( + 'FirebasePerformance#setPerformanceCollectionEnabled', + enable, + ); } /// Creates a [Trace] object with given [name]. @@ -55,22 +50,33 @@ class FirebasePerformance { /// underscore _ character, max length of [Trace.maxTraceNameLength] /// characters. Trace newTrace(String name) { - return Trace._(_traceCount++, name); + final String channelName = + '${FirebasePerformance.channel.name}/$Trace/${_channelCount++}'; + + FirebasePerformance.channel.invokeMethod( + '$FirebasePerformance#newTrace', + {'channelName': channelName, 'traceName': name}, + ); + + final MethodChannel channel = MethodChannel(channelName); + return Trace._(channel); } /// Creates [HttpMetric] for collecting performance for one request/response. HttpMetric newHttpMetric(String url, HttpMethod httpMethod) { - return HttpMetric._(_httpMetricCount++, url, httpMethod); - } + final String channelName = + '${FirebasePerformance.channel.name}/$HttpMetric/${_channelCount++}'; - /// Creates a [Trace] object with given [name] and start the trace. - /// - /// The [name] requires no leading or trailing whitespace, no leading - /// underscore _ character, max length of [Trace.maxTraceNameLength] - /// characters. - static Future startTrace(String name) async { - final Trace trace = instance.newTrace(name); - await trace.start(); - return trace; + FirebasePerformance.channel.invokeMethod( + '$FirebasePerformance#newHttpMetric', + { + 'channelName': channelName, + 'url': url, + 'httpMethod': httpMethod.toString(), + }, + ); + + final MethodChannel channel = MethodChannel(channelName); + return HttpMetric._(channel); } } diff --git a/packages/firebase_performance/lib/src/http_metric.dart b/packages/firebase_performance/lib/src/http_metric.dart index a2e221b368e1..7ee889c21742 100644 --- a/packages/firebase_performance/lib/src/http_metric.dart +++ b/packages/firebase_performance/lib/src/http_metric.dart @@ -16,14 +16,9 @@ part of firebase_performance; /// You can confirm that Performance Monitoring results appear in the Firebase /// console. Results should appear within 12 hours. class HttpMetric extends PerformanceAttributes { - HttpMetric._(this._handle, this._url, this._httpMethod); + HttpMetric._(this._channel); - final int _handle; - final String _url; - final HttpMethod _httpMethod; - - bool _hasStarted = false; - bool _hasStopped = false; + final MethodChannel _channel; /// HttpResponse code of the request. int httpResponseCode; @@ -37,75 +32,33 @@ class HttpMetric extends PerformanceAttributes { /// Size of the response payload. int responsePayloadSize; - /// Starts this httpmetric. - /// - /// Can only be called once, otherwise assertion error is thrown. + @override + MethodChannel get _methodChannel => null; + + /// Starts this [HttpMetric] asynchronously. /// /// Using ```await``` with this method is only necessary when accurate timing /// is relevant. Future start() { - assert(!_hasStarted); - - _hasStarted = true; - return FirebasePerformance.channel - // TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter. - // https://github.com/flutter/flutter/issues/26431 - // ignore: strong_mode_implicit_dynamic_method - .invokeMethod('HttpMetric#start', { - 'handle': _handle, - 'url': _url, - 'httpMethod': _httpMethod.index, - }); + return _channel.invokeMethod('$Trace#start'); } /// Stops this httpMetric. /// - /// Can only be called once and only after start(), otherwise assertion error - /// is thrown. Data collected is automatically sent to the associated - /// Firebase console after stop() is called. + /// Can only be called once and only after start(), Data collected is + /// automatically sent to the associate Firebase console after stop() is + /// called. You can confirm that Performance Monitoring results appear in the + /// Firebase console. Results should appear within 12 hours. /// /// Not necessary to use ```await``` with this method. Future stop() { - assert(!_hasStopped); - assert(_hasStarted); - final Map data = { - 'handle': _handle, 'httpResponseCode': httpResponseCode, 'requestPayloadSize': requestPayloadSize, 'responseContentType': responseContentType, 'responsePayloadSize': responsePayloadSize, - 'attributes': _attributes, }; - _hasStopped = true; - // TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter. - // https://github.com/flutter/flutter/issues/26431 - // ignore: strong_mode_implicit_dynamic_method - return FirebasePerformance.channel.invokeMethod('HttpMetric#stop', data); - } - - /// Sets a String [value] for the specified [attribute]. - /// - /// If the httpmetric has been stopped, this method throws an assertion - /// error. - /// - /// See [PerformanceAttributes.putAttribute]. - @override - void putAttribute(String attribute, String value) { - assert(!_hasStopped); - super.putAttribute(attribute, value); - } - - /// Removes an already added [attribute]. - /// - /// If the httpmetric has been stopped, this method throws an assertion - /// error. - /// - /// See [PerformanceAttributes.removeAttribute]. - @override - void removeAttribute(String attribute) { - assert(!_hasStopped); - super.removeAttribute(attribute); + return _channel.invokeMethod('$Trace#stop', data); } } diff --git a/packages/firebase_performance/lib/src/performance_attributes.dart b/packages/firebase_performance/lib/src/performance_attributes.dart index 0543242fdeb2..87237e7cac34 100644 --- a/packages/firebase_performance/lib/src/performance_attributes.dart +++ b/packages/firebase_performance/lib/src/performance_attributes.dart @@ -4,10 +4,7 @@ part of firebase_performance; -/// Abstract class that allows adding/removing attributes to any object. -/// -/// Enforces constraints for adding attributes and values required by -/// FirebasePerformance API. See [putAttribute]. +/// Abstract class that allows adding/removing attributes to an object. abstract class PerformanceAttributes { /// Maximum allowed length of a key passed to [putAttribute]. static const int maxAttributeKeyLength = 40; @@ -18,10 +15,7 @@ abstract class PerformanceAttributes { /// Maximum allowed number of attributes that can be added. static const int maxCustomAttributes = 5; - final Map _attributes = {}; - - /// Copy of all the attributes added. - Map get attributes => Map.from(_attributes); + MethodChannel get _methodChannel; /// Sets a String [value] for the specified [attribute]. /// @@ -32,22 +26,25 @@ abstract class PerformanceAttributes { /// Name of the attribute has max length of [maxAttributeKeyLength] /// characters. Value of the attribute has max length of /// [maxAttributeValueLength] characters. - void putAttribute(String attribute, String value) { - assert(attribute != null); - assert(!attribute.startsWith(RegExp(r'[_\s]'))); - assert(!attribute.contains(RegExp(r'[_\s]$'))); - assert(attribute.length <= maxAttributeKeyLength); - assert(value.length <= maxAttributeValueLength); - assert(_attributes.length < maxCustomAttributes); - - _attributes[attribute] = value; + Future putAttribute(String attribute, String value) { + return _methodChannel.invokeMethod( + 'PerformanceAttributes#putAttribute', + {'attribute': attribute, 'value': value}, + ); } /// Removes an already added [attribute]. - void removeAttribute(String attribute) { - _attributes.remove(attribute); + Future removeAttribute(String attribute) { + return _methodChannel.invokeMethod( + 'PerformanceAttributes#putAttribute', + attribute, + ); } - /// Returns the value of an [attribute]. - String getAttribute(String attribute) => _attributes[attribute]; + /// All [attribute]s added. + Future> getAttributes() { + return _methodChannel.invokeMapMethod( + 'PerformanceAttributes#getAttributes', + ); + } } diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index 6ff6ab996ee9..3187115a26b3 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -19,111 +19,69 @@ part of firebase_performance; /// You can confirm that Performance Monitoring results appear in the Firebase /// console. Results should appear within 12 hours. class Trace extends PerformanceAttributes { - Trace._(this._handle, this._name) { - assert(_name != null); - assert(!_name.startsWith(RegExp(r'[_\s]'))); - assert(!_name.contains(RegExp(r'[_\s]$'))); - assert(_name.length <= maxTraceNameLength); - } + Trace._(this._channel); /// Maximum allowed length of the name of a [Trace]. static const int maxTraceNameLength = 100; - final int _handle; - final String _name; - - bool _hasStarted = false; - bool _hasStopped = false; + final MethodChannel _channel; - final HashMap _counters = HashMap(); + @override + MethodChannel get _methodChannel => _channel; - /// Starts this trace. + /// Starts this [Trace] asynchronously. /// - /// Can only be called once, otherwise assertion error is thrown. + /// Can only be called once. /// /// Using ```await``` with this method is only necessary when accurate timing /// is relevant. Future start() { - assert(!_hasStarted); - - _hasStarted = true; - return FirebasePerformance.channel - // TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter. - // https://github.com/flutter/flutter/issues/26431 - // ignore: strong_mode_implicit_dynamic_method - .invokeMethod('Trace#start', { - 'handle': _handle, - 'name': _name, - }); + return _channel.invokeMethod('$Trace#start'); } - /// Stops this trace. + /// Stops this [Trace] asynchronously. /// - /// Can only be called once and only after start(), otherwise assertion error - /// is thrown. Data collected is automatically sent to the associated Firebase - /// console after stop() is called. + /// Can only be called once and only after start() Data collected is + /// automatically sent to the associated Firebase console after stop() is + /// called. /// /// Not necessary to use ```await``` with this method. Future stop() { - assert(!_hasStopped); - assert(_hasStarted); - - final Map data = { - 'handle': _handle, - 'name': _name, - 'counters': _counters, - 'attributes': _attributes, - }; - - _hasStopped = true; - // TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter. - // https://github.com/flutter/flutter/issues/26431 - // ignore: strong_mode_implicit_dynamic_method - return FirebasePerformance.channel.invokeMethod('Trace#stop', data); + return _channel.invokeMethod('$Trace#stop'); } - /// Increments the counter with the given [name] by [incrementBy]. + /// Increments the metric with the given name asynchronously. /// - /// The counter is incremented by 1 if [incrementBy] was not passed. If a - /// counter does not already exist, a new one will be created. If the trace - /// has not been started or has already been stopped, an assertion error is - /// thrown. - /// - /// The name of the counter requires no leading or - /// trailing whitespace, no leading underscore _ character, and max length of - /// 32 characters. - void incrementCounter(String name, [int incrementBy = 1]) { - assert(!_hasStopped); - assert(name != null); - assert(!name.startsWith(RegExp(r'[_\s]'))); - assert(!name.contains(RegExp(r'[_\s]$'))); - assert(name.length <= 32); - - _counters.putIfAbsent(name, () => 0); - _counters[name] += incrementBy; + /// If the metric does not exist, a new one will be created. If the trace has + /// not been started or has already been stopped, returns immediately without + /// taking action. + Future incrementMetric(String name, int value) { + return _channel.invokeMethod( + '$Trace#incrementMetric', + {'name': name, 'value': value}, + ); } - /// Sets a String [value] for the specified [attribute]. - /// - /// If the trace has been stopped, this method throws an assertion - /// error. + /// Sets the value of the metric with the given name asynchronously. /// - /// See [PerformanceAttributes.putAttribute]. - @override - void putAttribute(String attribute, String value) { - assert(!_hasStopped); - super.putAttribute(attribute, value); + /// If a metric with the given name doesn't exist, a new one will be created. + /// If the trace has not been started or has already been stopped, returns + /// immediately without taking action. + Future putMetric(String name, int value) { + return _channel.invokeMethod( + '$Trace#putMetric', + {'name': name, 'value': value}, + ); } - /// Removes an already added [attribute]. - /// - /// If the trace has been stopped, this method throws an assertion - /// error. + /// Gets the value of the metric with the given name asynchronously. /// - /// See [PerformanceAttributes.removeAttribute]. - @override - void removeAttribute(String attribute) { - assert(!_hasStopped); - super.removeAttribute(attribute); + /// If a metric with the given name doesn't exist, it is NOT created and a 0 + /// is returned. + Future getMetric(String name) { + return _channel.invokeMethod( + '$Trace#getMetric', + {'name': name}, + ); } } From b3d698cfda941c9c1e5e9de427a24d07ac03ffb0 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Mon, 22 Apr 2019 15:21:57 -0700 Subject: [PATCH 02/13] Undo changes --- packages/firebase_performance/lib/src/trace.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index 3187115a26b3..b4fc363bc1b6 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -9,7 +9,7 @@ part of firebase_performance; /// A trace is a report of performance data associated with some of the /// code in your app. You can have multiple custom traces, and it is /// possible to have more than one custom trace running at a time. Each custom -/// trace can have multiple counters and attributes added to help measure +/// trace can have multiple metrics and attributes added to help measure /// performance related events. A trace also measures the time between calling /// start() and stop(). /// @@ -74,7 +74,7 @@ class Trace extends PerformanceAttributes { ); } - /// Gets the value of the metric with the given name asynchronously. + /// Gets the value of the metric with the given name. /// /// If a metric with the given name doesn't exist, it is NOT created and a 0 /// is returned. From db5acb6432f29f2a88b8c48dbf06ac797f425858 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Tue, 23 Apr 2019 12:19:08 -0700 Subject: [PATCH 03/13] Update HttpMetric --- .../lib/src/firebase_performance.dart | 2 +- .../lib/src/http_metric.dart | 51 ++++++++++++------- .../lib/src/performance_attributes.dart | 6 +-- .../firebase_performance/lib/src/trace.dart | 5 +- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/packages/firebase_performance/lib/src/firebase_performance.dart b/packages/firebase_performance/lib/src/firebase_performance.dart index 165ed0851f87..f1640665ca64 100644 --- a/packages/firebase_performance/lib/src/firebase_performance.dart +++ b/packages/firebase_performance/lib/src/firebase_performance.dart @@ -47,7 +47,7 @@ class FirebasePerformance { /// Creates a [Trace] object with given [name]. /// /// The [name] requires no leading or trailing whitespace, no leading - /// underscore _ character, max length of [Trace.maxTraceNameLength] + /// underscore _ character, and max length of [Trace.maxTraceNameLength] /// characters. Trace newTrace(String name) { final String channelName = diff --git a/packages/firebase_performance/lib/src/http_metric.dart b/packages/firebase_performance/lib/src/http_metric.dart index 7ee889c21742..eb614139cd17 100644 --- a/packages/firebase_performance/lib/src/http_metric.dart +++ b/packages/firebase_performance/lib/src/http_metric.dart @@ -6,9 +6,9 @@ part of firebase_performance; /// Metric used to collect data for network requests/responses. /// -/// It is possible to have more than one httpmetric running at a time. +/// It is possible to have more than one [HttpMetric] running at a time. /// Attributes can also be added to help measure performance related events. A -/// httpmetric also measures the time between calling start() and stop(). +/// [HttpMetric] also measures the time between calling start() and stop(). /// /// Data collected is automatically sent to the associated Firebase console /// after stop() is called. @@ -20,30 +20,50 @@ class HttpMetric extends PerformanceAttributes { final MethodChannel _channel; + @override + MethodChannel get _methodChannel => _channel; + /// HttpResponse code of the request. - int httpResponseCode; + set httpResponseCode(int httpResponseCode) { + _channel.invokeMethod( + '$HttpMetric#httpResponseCode', + httpResponseCode, + ); + } /// Size of the request payload. - int requestPayloadSize; + set requestPayloadSize(int requestPayloadSize) { + _channel.invokeMethod( + '$HttpMetric#requestPayloadSize', + requestPayloadSize, + ); + } /// Content type of the response such as text/html, application/json, etc... - String responseContentType; + set responseContentType(String responseContentType) { + _channel.invokeMethod( + '$HttpMetric#responseContentType', + responseContentType, + ); + } /// Size of the response payload. - int responsePayloadSize; - - @override - MethodChannel get _methodChannel => null; + set responsePayloadSize(int responsePayloadSize) { + _channel.invokeMethod( + '$HttpMetric#responsePayloadSize', + responsePayloadSize, + ); + } /// Starts this [HttpMetric] asynchronously. /// /// Using ```await``` with this method is only necessary when accurate timing /// is relevant. Future start() { - return _channel.invokeMethod('$Trace#start'); + return _channel.invokeMethod('$HttpMetric#start'); } - /// Stops this httpMetric. + /// Stops this [HttpMetric]. /// /// Can only be called once and only after start(), Data collected is /// automatically sent to the associate Firebase console after stop() is @@ -52,13 +72,6 @@ class HttpMetric extends PerformanceAttributes { /// /// Not necessary to use ```await``` with this method. Future stop() { - final Map data = { - 'httpResponseCode': httpResponseCode, - 'requestPayloadSize': requestPayloadSize, - 'responseContentType': responseContentType, - 'responsePayloadSize': responsePayloadSize, - }; - - return _channel.invokeMethod('$Trace#stop', data); + return _channel.invokeMethod('$HttpMetric#stop'); } } diff --git a/packages/firebase_performance/lib/src/performance_attributes.dart b/packages/firebase_performance/lib/src/performance_attributes.dart index 87237e7cac34..b9247e73b1b0 100644 --- a/packages/firebase_performance/lib/src/performance_attributes.dart +++ b/packages/firebase_performance/lib/src/performance_attributes.dart @@ -28,7 +28,7 @@ abstract class PerformanceAttributes { /// [maxAttributeValueLength] characters. Future putAttribute(String attribute, String value) { return _methodChannel.invokeMethod( - 'PerformanceAttributes#putAttribute', + '$PerformanceAttributes#putAttribute', {'attribute': attribute, 'value': value}, ); } @@ -36,7 +36,7 @@ abstract class PerformanceAttributes { /// Removes an already added [attribute]. Future removeAttribute(String attribute) { return _methodChannel.invokeMethod( - 'PerformanceAttributes#putAttribute', + '$PerformanceAttributes#putAttribute', attribute, ); } @@ -44,7 +44,7 @@ abstract class PerformanceAttributes { /// All [attribute]s added. Future> getAttributes() { return _methodChannel.invokeMapMethod( - 'PerformanceAttributes#getAttributes', + '$PerformanceAttributes#getAttributes', ); } } diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index b4fc363bc1b6..5298ea5dde06 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -4,7 +4,7 @@ part of firebase_performance; -/// Trace allows you to set the beginning and end of a custom trace in your app. +/// [Trace] allows you to set the beginning and end of a custom trace in your app. /// /// A trace is a report of performance data associated with some of the /// code in your app. You can have multiple custom traces, and it is @@ -43,7 +43,8 @@ class Trace extends PerformanceAttributes { /// /// Can only be called once and only after start() Data collected is /// automatically sent to the associated Firebase console after stop() is - /// called. + /// called. You can confirm that Performance Monitoring results appear in the + /// Firebase console. Results should appear within 12 hours. /// /// Not necessary to use ```await``` with this method. Future stop() { From 236da2c737cb5e903c2dfb1780fe557c7f44c623 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Tue, 23 Apr 2019 13:37:14 -0700 Subject: [PATCH 04/13] Fix MethodChannel Unit tests --- .../lib/src/http_metric.dart | 19 +- .../lib/src/performance_attributes.dart | 11 +- .../firebase_performance/lib/src/trace.dart | 17 +- .../test/firebase_performance_test.dart | 359 +++++++----------- 4 files changed, 165 insertions(+), 241 deletions(-) diff --git a/packages/firebase_performance/lib/src/http_metric.dart b/packages/firebase_performance/lib/src/http_metric.dart index eb614139cd17..aeabb8024c95 100644 --- a/packages/firebase_performance/lib/src/http_metric.dart +++ b/packages/firebase_performance/lib/src/http_metric.dart @@ -16,16 +16,17 @@ part of firebase_performance; /// You can confirm that Performance Monitoring results appear in the Firebase /// console. Results should appear within 12 hours. class HttpMetric extends PerformanceAttributes { - HttpMetric._(this._channel); + HttpMetric._(this.channel); - final MethodChannel _channel; + @visibleForTesting + final MethodChannel channel; @override - MethodChannel get _methodChannel => _channel; + MethodChannel get methodChannel => channel; /// HttpResponse code of the request. set httpResponseCode(int httpResponseCode) { - _channel.invokeMethod( + channel.invokeMethod( '$HttpMetric#httpResponseCode', httpResponseCode, ); @@ -33,7 +34,7 @@ class HttpMetric extends PerformanceAttributes { /// Size of the request payload. set requestPayloadSize(int requestPayloadSize) { - _channel.invokeMethod( + channel.invokeMethod( '$HttpMetric#requestPayloadSize', requestPayloadSize, ); @@ -41,7 +42,7 @@ class HttpMetric extends PerformanceAttributes { /// Content type of the response such as text/html, application/json, etc... set responseContentType(String responseContentType) { - _channel.invokeMethod( + channel.invokeMethod( '$HttpMetric#responseContentType', responseContentType, ); @@ -49,7 +50,7 @@ class HttpMetric extends PerformanceAttributes { /// Size of the response payload. set responsePayloadSize(int responsePayloadSize) { - _channel.invokeMethod( + channel.invokeMethod( '$HttpMetric#responsePayloadSize', responsePayloadSize, ); @@ -60,7 +61,7 @@ class HttpMetric extends PerformanceAttributes { /// Using ```await``` with this method is only necessary when accurate timing /// is relevant. Future start() { - return _channel.invokeMethod('$HttpMetric#start'); + return channel.invokeMethod('$HttpMetric#start'); } /// Stops this [HttpMetric]. @@ -72,6 +73,6 @@ class HttpMetric extends PerformanceAttributes { /// /// Not necessary to use ```await``` with this method. Future stop() { - return _channel.invokeMethod('$HttpMetric#stop'); + return channel.invokeMethod('$HttpMetric#stop'); } } diff --git a/packages/firebase_performance/lib/src/performance_attributes.dart b/packages/firebase_performance/lib/src/performance_attributes.dart index b9247e73b1b0..b74869e11878 100644 --- a/packages/firebase_performance/lib/src/performance_attributes.dart +++ b/packages/firebase_performance/lib/src/performance_attributes.dart @@ -15,7 +15,8 @@ abstract class PerformanceAttributes { /// Maximum allowed number of attributes that can be added. static const int maxCustomAttributes = 5; - MethodChannel get _methodChannel; + @visibleForTesting + MethodChannel get methodChannel; /// Sets a String [value] for the specified [attribute]. /// @@ -27,7 +28,7 @@ abstract class PerformanceAttributes { /// characters. Value of the attribute has max length of /// [maxAttributeValueLength] characters. Future putAttribute(String attribute, String value) { - return _methodChannel.invokeMethod( + return methodChannel.invokeMethod( '$PerformanceAttributes#putAttribute', {'attribute': attribute, 'value': value}, ); @@ -35,15 +36,15 @@ abstract class PerformanceAttributes { /// Removes an already added [attribute]. Future removeAttribute(String attribute) { - return _methodChannel.invokeMethod( - '$PerformanceAttributes#putAttribute', + return methodChannel.invokeMethod( + '$PerformanceAttributes#removeAttribute', attribute, ); } /// All [attribute]s added. Future> getAttributes() { - return _methodChannel.invokeMapMethod( + return methodChannel.invokeMapMethod( '$PerformanceAttributes#getAttributes', ); } diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index 5298ea5dde06..cda5c066fecc 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -19,15 +19,16 @@ part of firebase_performance; /// You can confirm that Performance Monitoring results appear in the Firebase /// console. Results should appear within 12 hours. class Trace extends PerformanceAttributes { - Trace._(this._channel); + Trace._(this.channel); /// Maximum allowed length of the name of a [Trace]. static const int maxTraceNameLength = 100; - final MethodChannel _channel; + @visibleForTesting + final MethodChannel channel; @override - MethodChannel get _methodChannel => _channel; + MethodChannel get methodChannel => channel; /// Starts this [Trace] asynchronously. /// @@ -36,7 +37,7 @@ class Trace extends PerformanceAttributes { /// Using ```await``` with this method is only necessary when accurate timing /// is relevant. Future start() { - return _channel.invokeMethod('$Trace#start'); + return channel.invokeMethod('$Trace#start'); } /// Stops this [Trace] asynchronously. @@ -48,7 +49,7 @@ class Trace extends PerformanceAttributes { /// /// Not necessary to use ```await``` with this method. Future stop() { - return _channel.invokeMethod('$Trace#stop'); + return channel.invokeMethod('$Trace#stop'); } /// Increments the metric with the given name asynchronously. @@ -57,7 +58,7 @@ class Trace extends PerformanceAttributes { /// not been started or has already been stopped, returns immediately without /// taking action. Future incrementMetric(String name, int value) { - return _channel.invokeMethod( + return channel.invokeMethod( '$Trace#incrementMetric', {'name': name, 'value': value}, ); @@ -69,7 +70,7 @@ class Trace extends PerformanceAttributes { /// If the trace has not been started or has already been stopped, returns /// immediately without taking action. Future putMetric(String name, int value) { - return _channel.invokeMethod( + return channel.invokeMethod( '$Trace#putMetric', {'name': name, 'value': value}, ); @@ -80,7 +81,7 @@ class Trace extends PerformanceAttributes { /// If a metric with the given name doesn't exist, it is NOT created and a 0 /// is returned. Future getMetric(String name) { - return _channel.invokeMethod( + return channel.invokeMethod( '$Trace#getMetric', {'name': name}, ); diff --git a/packages/firebase_performance/test/firebase_performance_test.dart b/packages/firebase_performance/test/firebase_performance_test.dart index bf2b42e50499..cf45623f5f41 100644 --- a/packages/firebase_performance/test/firebase_performance_test.dart +++ b/packages/firebase_performance/test/firebase_performance_test.dart @@ -7,15 +7,10 @@ import 'package:flutter/services.dart'; import 'package:firebase_performance/firebase_performance.dart'; import 'package:flutter_test/flutter_test.dart'; -class MockPerformanceAttributes extends PerformanceAttributes {} - void main() { group('$FirebasePerformance', () { final FirebasePerformance performance = FirebasePerformance.instance; final List log = []; - bool performanceCollectionEnable = true; - int currentTraceHandle; - int currentHttpMetricHandle; setUp(() { FirebasePerformance.channel @@ -23,20 +18,7 @@ void main() { log.add(methodCall); switch (methodCall.method) { case 'FirebasePerformance#isPerformanceCollectionEnabled': - return performanceCollectionEnable; - case 'FirebasePerformance#setPerformanceCollectionEnabled': - performanceCollectionEnable = methodCall.arguments; - return null; - case 'Trace#start': - currentTraceHandle = methodCall.arguments['handle']; - return null; - case 'Trace#stop': - return null; - case 'HttpMetric#start': - currentHttpMetricHandle = methodCall.arguments['handle']; - return null; - case 'HttpMetric#stop': - return null; + return true; default: return null; } @@ -47,7 +29,7 @@ void main() { test('isPerformanceCollectionEnabled', () async { final bool enabled = await performance.isPerformanceCollectionEnabled(); - expect(performanceCollectionEnable, enabled); + expect(enabled, isTrue); expect(log, [ isMethodCall( 'FirebasePerformance#isPerformanceCollectionEnabled', @@ -58,10 +40,7 @@ void main() { test('setPerformanceCollectionEnabled', () async { await performance.setPerformanceCollectionEnabled(true); - performanceCollectionEnable = true; - await performance.setPerformanceCollectionEnabled(false); - performanceCollectionEnable = false; expect(log, [ isMethodCall( @@ -77,188 +56,121 @@ void main() { test('newTrace', () async { final Trace trace = performance.newTrace('test-trace'); - await trace.start(); + + await pumpEventQueue(); expect(log, [ isMethodCall( - 'Trace#start', - arguments: { - 'handle': currentTraceHandle, - 'name': 'test-trace', + 'FirebasePerformance#newTrace', + arguments: { + 'channelName': trace.channel.name, + 'traceName': 'test-trace', }, ), ]); }); test('newHttpMetric', () async { + final String url = 'https://google.com'; + final HttpMetric metric = performance.newHttpMetric( - 'https://google.com', + url, HttpMethod.Connect, ); - await metric.start(); - expect(log, [ - isMethodCall( - 'HttpMetric#start', - arguments: { - 'handle': currentTraceHandle, - 'url': 'https://google.com', - 'httpMethod': HttpMethod.Connect.index, - }, - ), - ]); - }); - - test('startTrace', () async { - await FirebasePerformance.startTrace('startTrace-test'); + await pumpEventQueue(); expect(log, [ isMethodCall( - 'Trace#start', - arguments: { - 'handle': currentTraceHandle, - 'name': 'startTrace-test', + 'FirebasePerformance#newHttpMetric', + arguments: { + 'channelName': metric.channel.name, + 'url': url, + 'httpMethod': HttpMethod.Connect.toString(), }, ), ]); }); test('$HttpMethod', () async { - expect(HttpMethod.Connect.index, 0); - expect(HttpMethod.Delete.index, 1); - expect(HttpMethod.Get.index, 2); - expect(HttpMethod.Head.index, 3); - expect(HttpMethod.Options.index, 4); - expect(HttpMethod.Patch.index, 5); - expect(HttpMethod.Post.index, 6); - expect(HttpMethod.Put.index, 7); - expect(HttpMethod.Trace.index, 8); + final String url = 'https://google.com'; + + for (HttpMethod method in HttpMethod.values) { + final HttpMetric metric = performance.newHttpMetric( + 'https://google.com', + method, + ); + + await pumpEventQueue(); + + expect(log, [ + isMethodCall( + 'FirebasePerformance#newHttpMetric', + arguments: { + 'channelName': metric.channel.name, + 'url': url, + 'httpMethod': method.toString(), + }, + ), + ]); + + log.clear(); + } }); group('$Trace', () { Trace testTrace; + final List traceLog = []; setUp(() { testTrace = performance.newTrace('test'); + testTrace.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + traceLog.add(methodCall); + switch (methodCall.method) { + case 'FirebasePerformance#isPerformanceCollectionEnabled': + return true; + default: + return null; + } + }); + traceLog.clear(); }); test('start', () async { + await pumpEventQueue(); + await testTrace.start(); - expect(log, [ - isMethodCall( - 'Trace#start', - arguments: { - 'handle': currentTraceHandle, - 'name': 'test', - }, - ), + expect(traceLog, [ + isMethodCall('Trace#start', arguments: null), ]); }); test('stop', () async { - await testTrace.start(); + await pumpEventQueue(); + await testTrace.stop(); - expect(log, [ - isMethodCall('Trace#start', arguments: { - 'handle': currentTraceHandle, - 'name': 'test', - }), - isMethodCall( - 'Trace#stop', - arguments: { - 'handle': currentTraceHandle, - 'name': 'test', - 'metrics': {}, - 'attributes': {}, - }, - ), - ]); - }); - - test('incrementCounter', () async { - final Trace trace = performance.newTrace('test'); - - // ignore: deprecated_member_use_from_same_package - trace.incrementCounter('counter1'); - - // ignore: deprecated_member_use_from_same_package - trace.incrementCounter('counter2'); - // ignore: deprecated_member_use_from_same_package - trace.incrementCounter('counter2'); - - // ignore: deprecated_member_use_from_same_package - trace.incrementCounter('counter3', 5); - // ignore: deprecated_member_use_from_same_package - trace.incrementCounter('counter3', 5); - - // ignore: deprecated_member_use_from_same_package - trace.incrementCounter('counter4', -5); - - await trace.start(); - await trace.stop(); - - expect(log, [ - isMethodCall( - 'Trace#start', - arguments: { - 'handle': currentTraceHandle, - 'name': 'test', - }, - ), - isMethodCall( - 'Trace#stop', - arguments: { - 'handle': currentTraceHandle, - 'name': 'test', - 'metrics': { - 'counter1': 1, - 'counter2': 2, - 'counter3': 10, - 'counter4': -5, - }, - 'attributes': {}, - }, - ), + expect(traceLog, [ + isMethodCall('Trace#stop', arguments: null), ]); }); test('incrementMetric', () async { - final Trace trace = performance.newTrace('test'); - trace.incrementMetric('metric1', 1); - - trace.incrementMetric('metric2', 1); - trace.incrementMetric('metric2', 1); - - trace.incrementMetric('metric3', 5); - trace.incrementMetric('metric3', 5); + await pumpEventQueue(); - trace.incrementMetric('metric4', -5); + final String name = 'counter1'; + final int value = 45; - await trace.start(); - await trace.stop(); + testTrace.incrementMetric(name, value); - expect(log, [ + expect(traceLog, [ isMethodCall( - 'Trace#start', - arguments: { - 'handle': currentTraceHandle, - 'name': 'test', - }, - ), - isMethodCall( - 'Trace#stop', + 'Trace#incrementMetric', arguments: { - 'handle': currentTraceHandle, - 'name': 'test', - 'metrics': { - 'metric1': 1, - 'metric2': 2, - 'metric3': 10, - 'metric4': -5, - }, - 'attributes': {}, + 'name': name, + 'value': value, }, ), ]); @@ -267,106 +179,115 @@ void main() { group('$HttpMetric', () { HttpMetric testMetric; + final List httpMetricLog = []; setUp(() { testMetric = performance.newHttpMetric( 'https://google.com', HttpMethod.Get, ); + testMetric.channel + .setMockMethodCallHandler((MethodCall methodCall) async { + httpMetricLog.add(methodCall); + switch (methodCall.method) { + case 'FirebasePerformance#isPerformanceCollectionEnabled': + return true; + default: + return null; + } + }); + httpMetricLog.clear(); }); test('start', () async { + await pumpEventQueue(); + await testMetric.start(); - expect(log, [ - isMethodCall( - 'HttpMetric#start', - arguments: { - 'handle': currentHttpMetricHandle, - 'url': 'https://google.com', - 'httpMethod': HttpMethod.Get.index, - }, - ), + expect(httpMetricLog, [ + isMethodCall('HttpMetric#start', arguments: null), ]); }); test('stop', () async { - testMetric.httpResponseCode = 1; - testMetric.requestPayloadSize = 5000000; - testMetric.responseContentType = 'text/html'; - testMetric.responsePayloadSize = 1992304820934820; + await pumpEventQueue(); - await testMetric.start(); await testMetric.stop(); - expect(log, [ - isMethodCall( - 'HttpMetric#start', - arguments: { - 'handle': currentHttpMetricHandle, - 'url': 'https://google.com', - 'httpMethod': HttpMethod.Get.index, - }, - ), - isMethodCall( - 'HttpMetric#stop', - arguments: { - 'handle': currentHttpMetricHandle, - 'httpResponseCode': 1, - 'requestPayloadSize': 5000000, - 'responseContentType': 'text/html', - 'responsePayloadSize': 1992304820934820, - 'attributes': {}, - }, - ), + expect(httpMetricLog, [ + isMethodCall('HttpMetric#stop', arguments: null), ]); }); }); group('$PerformanceAttributes', () { - PerformanceAttributes attributes; + final PerformanceAttributes attributes = MockPerformanceAttributes(); + final List attributeLog = []; + final Map getAttributesResult = { + 'a1': 'hello', + 'a2': 'friend', + }; setUp(() { - attributes = MockPerformanceAttributes(); + MockPerformanceAttributes._channel + .setMockMethodCallHandler((MethodCall methodCall) async { + attributeLog.add(methodCall); + if (methodCall.method == 'PerformanceAttributes#getAttributes') { + return getAttributesResult; + } + + return null; + }); + attributeLog.clear(); }); test('putAttribute', () async { - attributes.putAttribute('attr1', 'apple'); - attributes.putAttribute('attr2', 'are'); - expect(attributes.attributes, { - 'attr1': 'apple', - 'attr2': 'are', - }); + final String attribute = 'attr1'; + final String value = 'apple'; + await attributes.putAttribute(attribute, value); - attributes.putAttribute('attr1', 'delicious'); - expect(attributes.attributes, { - 'attr1': 'delicious', - 'attr2': 'are', - }); + expect(attributeLog, [ + isMethodCall( + 'PerformanceAttributes#putAttribute', + arguments: { + 'attribute': attribute, + 'value': value, + }, + ), + ]); }); test('removeAttribute', () async { - attributes.putAttribute('attr1', 'apple'); - attributes.putAttribute('attr2', 'are'); - attributes.removeAttribute('no-attr'); - expect(attributes.attributes, { - 'attr1': 'apple', - 'attr2': 'are', - }); + final String attribute = 'attr1'; + await attributes.removeAttribute(attribute); - attributes.removeAttribute('attr1'); - expect(attributes.attributes, { - 'attr2': 'are', - }); + expect(attributeLog, [ + isMethodCall( + 'PerformanceAttributes#removeAttribute', + arguments: attribute, + ), + ]); }); - test('getAttribute', () { - attributes.putAttribute('attr1', 'apple'); - attributes.putAttribute('attr2', 'are'); - expect(attributes.getAttribute('attr1'), 'apple'); + test('getAttributes', () async { + final Map result = await attributes.getAttributes(); + + expect(attributeLog, [ + isMethodCall( + 'PerformanceAttributes#getAttributes', + arguments: null, + ), + ]); - expect(attributes.getAttribute('attr3'), isNull); + expect(result, getAttributesResult); }); }); }); } + +class MockPerformanceAttributes extends PerformanceAttributes { + static MethodChannel _channel = const MethodChannel('testMethodChannel'); + + @override + MethodChannel get methodChannel => _channel; +} From 8a8ab7725817205f3389551a789d5d7053e6ad6a Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Tue, 23 Apr 2019 15:01:59 -0700 Subject: [PATCH 05/13] Remove awaits and ayncs --- .../test/firebase_performance_test.dart | 101 ++++++++---------- 1 file changed, 46 insertions(+), 55 deletions(-) diff --git a/packages/firebase_performance/test/firebase_performance_test.dart b/packages/firebase_performance/test/firebase_performance_test.dart index cf45623f5f41..42b8f67e7c24 100644 --- a/packages/firebase_performance/test/firebase_performance_test.dart +++ b/packages/firebase_performance/test/firebase_performance_test.dart @@ -11,6 +11,7 @@ void main() { group('$FirebasePerformance', () { final FirebasePerformance performance = FirebasePerformance.instance; final List log = []; + bool isPerformanceCollectionEnabledResult; setUp(() { FirebasePerformance.channel @@ -18,7 +19,7 @@ void main() { log.add(methodCall); switch (methodCall.method) { case 'FirebasePerformance#isPerformanceCollectionEnabled': - return true; + return isPerformanceCollectionEnabledResult; default: return null; } @@ -27,20 +28,29 @@ void main() { }); test('isPerformanceCollectionEnabled', () async { + isPerformanceCollectionEnabledResult = true; final bool enabled = await performance.isPerformanceCollectionEnabled(); - expect(enabled, isTrue); + + isPerformanceCollectionEnabledResult = false; + final bool disabled = await performance.isPerformanceCollectionEnabled(); + expect(disabled, isFalse); + expect(log, [ isMethodCall( 'FirebasePerformance#isPerformanceCollectionEnabled', arguments: null, ), + isMethodCall( + 'FirebasePerformance#isPerformanceCollectionEnabled', + arguments: null, + ), ]); }); - test('setPerformanceCollectionEnabled', () async { - await performance.setPerformanceCollectionEnabled(true); - await performance.setPerformanceCollectionEnabled(false); + test('setPerformanceCollectionEnabled', () { + performance.setPerformanceCollectionEnabled(true); + performance.setPerformanceCollectionEnabled(false); expect(log, [ isMethodCall( @@ -54,11 +64,9 @@ void main() { ]); }); - test('newTrace', () async { + test('newTrace', () { final Trace trace = performance.newTrace('test-trace'); - await pumpEventQueue(); - expect(log, [ isMethodCall( 'FirebasePerformance#newTrace', @@ -70,7 +78,7 @@ void main() { ]); }); - test('newHttpMetric', () async { + test('newHttpMetric', () { final String url = 'https://google.com'; final HttpMetric metric = performance.newHttpMetric( @@ -78,8 +86,6 @@ void main() { HttpMethod.Connect, ); - await pumpEventQueue(); - expect(log, [ isMethodCall( 'FirebasePerformance#newHttpMetric', @@ -92,30 +98,25 @@ void main() { ]); }); - test('$HttpMethod', () async { + test('$HttpMethod', () { final String url = 'https://google.com'; + final HttpMethod method = HttpMethod.Connect; - for (HttpMethod method in HttpMethod.values) { - final HttpMetric metric = performance.newHttpMetric( - 'https://google.com', - method, - ); - - await pumpEventQueue(); - - expect(log, [ - isMethodCall( - 'FirebasePerformance#newHttpMetric', - arguments: { - 'channelName': metric.channel.name, - 'url': url, - 'httpMethod': method.toString(), - }, - ), - ]); + final HttpMetric metric = performance.newHttpMetric( + 'https://google.com', + method, + ); - log.clear(); - } + expect(log, [ + isMethodCall( + 'FirebasePerformance#newHttpMetric', + arguments: { + 'channelName': metric.channel.name, + 'url': url, + 'httpMethod': method.toString(), + }, + ), + ]); }); group('$Trace', () { @@ -137,29 +138,23 @@ void main() { traceLog.clear(); }); - test('start', () async { - await pumpEventQueue(); - - await testTrace.start(); + test('start', () { + testTrace.start(); expect(traceLog, [ isMethodCall('Trace#start', arguments: null), ]); }); - test('stop', () async { - await pumpEventQueue(); - - await testTrace.stop(); + test('stop', () { + testTrace.stop(); expect(traceLog, [ isMethodCall('Trace#stop', arguments: null), ]); }); - test('incrementMetric', () async { - await pumpEventQueue(); - + test('incrementMetric', () { final String name = 'counter1'; final int value = 45; @@ -199,20 +194,16 @@ void main() { httpMetricLog.clear(); }); - test('start', () async { - await pumpEventQueue(); - - await testMetric.start(); + test('start', () { + testMetric.start(); expect(httpMetricLog, [ isMethodCall('HttpMetric#start', arguments: null), ]); }); - test('stop', () async { - await pumpEventQueue(); - - await testMetric.stop(); + test('stop', () { + testMetric.stop(); expect(httpMetricLog, [ isMethodCall('HttpMetric#stop', arguments: null), @@ -241,10 +232,10 @@ void main() { attributeLog.clear(); }); - test('putAttribute', () async { + test('putAttribute', () { final String attribute = 'attr1'; final String value = 'apple'; - await attributes.putAttribute(attribute, value); + attributes.putAttribute(attribute, value); expect(attributeLog, [ isMethodCall( @@ -257,9 +248,9 @@ void main() { ]); }); - test('removeAttribute', () async { + test('removeAttribute', () { final String attribute = 'attr1'; - await attributes.removeAttribute(attribute); + attributes.removeAttribute(attribute); expect(attributeLog, [ isMethodCall( From 3c3ed91e6cc27c89e8c37e151529c85ce1d9aea9 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Tue, 23 Apr 2019 15:02:44 -0700 Subject: [PATCH 06/13] Remove mentions of asynchronous --- .../lib/src/firebase_performance.dart | 2 +- packages/firebase_performance/lib/src/http_metric.dart | 2 +- packages/firebase_performance/lib/src/trace.dart | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/firebase_performance/lib/src/firebase_performance.dart b/packages/firebase_performance/lib/src/firebase_performance.dart index f1640665ca64..5b9e044b47e1 100644 --- a/packages/firebase_performance/lib/src/firebase_performance.dart +++ b/packages/firebase_performance/lib/src/firebase_performance.dart @@ -33,7 +33,7 @@ class FirebasePerformance { ); } - /// Enables or disables performance monitoring asynchronously. + /// Enables or disables performance monitoring. /// /// This setting is persisted and applied on future invocations of your /// application. By default, performance monitoring is enabled. diff --git a/packages/firebase_performance/lib/src/http_metric.dart b/packages/firebase_performance/lib/src/http_metric.dart index aeabb8024c95..67b3ba1b40ab 100644 --- a/packages/firebase_performance/lib/src/http_metric.dart +++ b/packages/firebase_performance/lib/src/http_metric.dart @@ -56,7 +56,7 @@ class HttpMetric extends PerformanceAttributes { ); } - /// Starts this [HttpMetric] asynchronously. + /// Starts this [HttpMetric]. /// /// Using ```await``` with this method is only necessary when accurate timing /// is relevant. diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index cda5c066fecc..936f9204d55c 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -30,7 +30,7 @@ class Trace extends PerformanceAttributes { @override MethodChannel get methodChannel => channel; - /// Starts this [Trace] asynchronously. + /// Starts this [Trace]. /// /// Can only be called once. /// @@ -40,7 +40,7 @@ class Trace extends PerformanceAttributes { return channel.invokeMethod('$Trace#start'); } - /// Stops this [Trace] asynchronously. + /// Stops this [Trace]. /// /// Can only be called once and only after start() Data collected is /// automatically sent to the associated Firebase console after stop() is @@ -52,7 +52,7 @@ class Trace extends PerformanceAttributes { return channel.invokeMethod('$Trace#stop'); } - /// Increments the metric with the given name asynchronously. + /// Increments the metric with the given name. /// /// If the metric does not exist, a new one will be created. If the trace has /// not been started or has already been stopped, returns immediately without @@ -64,7 +64,7 @@ class Trace extends PerformanceAttributes { ); } - /// Sets the value of the metric with the given name asynchronously. + /// Sets the value of the metric with the given name. /// /// If a metric with the given name doesn't exist, a new one will be created. /// If the trace has not been started or has already been stopped, returns From bd971abcb02f25cc535d9017747a1eb4a272b2f7 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Tue, 23 Apr 2019 16:56:29 -0700 Subject: [PATCH 07/13] cache state --- .../lib/src/firebase_performance.dart | 2 +- .../lib/src/http_metric.dart | 20 +++++++++++ .../lib/src/performance_attributes.dart | 24 +++++++++++++- .../firebase_performance/lib/src/trace.dart | 26 +++++++++++++++ .../test/firebase_performance_test.dart | 33 +++++++++---------- 5 files changed, 86 insertions(+), 19 deletions(-) diff --git a/packages/firebase_performance/lib/src/firebase_performance.dart b/packages/firebase_performance/lib/src/firebase_performance.dart index 5b9e044b47e1..d4843dcf245a 100644 --- a/packages/firebase_performance/lib/src/firebase_performance.dart +++ b/packages/firebase_performance/lib/src/firebase_performance.dart @@ -37,7 +37,7 @@ class FirebasePerformance { /// /// This setting is persisted and applied on future invocations of your /// application. By default, performance monitoring is enabled. - Future setPerformanceCollectionEnabled(bool enable) async { + Future setPerformanceCollectionEnabled(bool enable) { return channel.invokeMethod( 'FirebasePerformance#setPerformanceCollectionEnabled', enable, diff --git a/packages/firebase_performance/lib/src/http_metric.dart b/packages/firebase_performance/lib/src/http_metric.dart index 67b3ba1b40ab..c7669571b5c1 100644 --- a/packages/firebase_performance/lib/src/http_metric.dart +++ b/packages/firebase_performance/lib/src/http_metric.dart @@ -21,11 +21,19 @@ class HttpMetric extends PerformanceAttributes { @visibleForTesting final MethodChannel channel; + @override + bool _hasStarted = false; + + @override + bool _hasStopped = false; + @override MethodChannel get methodChannel => channel; /// HttpResponse code of the request. set httpResponseCode(int httpResponseCode) { + if (_hasStopped) return; + channel.invokeMethod( '$HttpMetric#httpResponseCode', httpResponseCode, @@ -34,6 +42,8 @@ class HttpMetric extends PerformanceAttributes { /// Size of the request payload. set requestPayloadSize(int requestPayloadSize) { + if (_hasStopped) return; + channel.invokeMethod( '$HttpMetric#requestPayloadSize', requestPayloadSize, @@ -42,6 +52,8 @@ class HttpMetric extends PerformanceAttributes { /// Content type of the response such as text/html, application/json, etc... set responseContentType(String responseContentType) { + if (_hasStopped) return; + channel.invokeMethod( '$HttpMetric#responseContentType', responseContentType, @@ -50,6 +62,8 @@ class HttpMetric extends PerformanceAttributes { /// Size of the response payload. set responsePayloadSize(int responsePayloadSize) { + if (_hasStopped) return; + channel.invokeMethod( '$HttpMetric#responsePayloadSize', responsePayloadSize, @@ -61,6 +75,9 @@ class HttpMetric extends PerformanceAttributes { /// Using ```await``` with this method is only necessary when accurate timing /// is relevant. Future start() { + if (_hasStarted || _hasStopped) return Future.value(null); + + _hasStarted = true; return channel.invokeMethod('$HttpMetric#start'); } @@ -73,6 +90,9 @@ class HttpMetric extends PerformanceAttributes { /// /// Not necessary to use ```await``` with this method. Future stop() { + if (_hasStopped) return Future.value(null); + + _hasStopped = true; return channel.invokeMethod('$HttpMetric#stop'); } } diff --git a/packages/firebase_performance/lib/src/performance_attributes.dart b/packages/firebase_performance/lib/src/performance_attributes.dart index b74869e11878..09411e2d9079 100644 --- a/packages/firebase_performance/lib/src/performance_attributes.dart +++ b/packages/firebase_performance/lib/src/performance_attributes.dart @@ -15,8 +15,12 @@ abstract class PerformanceAttributes { /// Maximum allowed number of attributes that can be added. static const int maxCustomAttributes = 5; + final Map _attributes = {}; + @visibleForTesting MethodChannel get methodChannel; + bool get _hasStarted; + bool get _hasStopped; /// Sets a String [value] for the specified [attribute]. /// @@ -28,6 +32,15 @@ abstract class PerformanceAttributes { /// characters. Value of the attribute has max length of /// [maxAttributeValueLength] characters. Future putAttribute(String attribute, String value) { + if (!_hasStarted || + _hasStopped || + attribute.length > maxAttributeKeyLength || + value.length > maxAttributeValueLength || + _attributes.length == 5) { + return Future.value(null); + } + + _attributes[attribute] = value; return methodChannel.invokeMethod( '$PerformanceAttributes#putAttribute', {'attribute': attribute, 'value': value}, @@ -36,14 +49,23 @@ abstract class PerformanceAttributes { /// Removes an already added [attribute]. Future removeAttribute(String attribute) { + if (!_hasStarted || _hasStopped) return Future.value(null); + + _attributes.remove(attribute); return methodChannel.invokeMethod( '$PerformanceAttributes#removeAttribute', attribute, ); } - /// All [attribute]s added. + /// All attributes added. Future> getAttributes() { + if (_hasStopped) { + return Future>.value(Map.unmodifiable( + _attributes, + )); + } + return methodChannel.invokeMapMethod( '$PerformanceAttributes#getAttributes', ); diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index 936f9204d55c..fc406199f900 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -27,6 +27,14 @@ class Trace extends PerformanceAttributes { @visibleForTesting final MethodChannel channel; + final Map _metrics = {}; + + @override + bool _hasStarted = false; + + @override + bool _hasStopped = false; + @override MethodChannel get methodChannel => channel; @@ -37,6 +45,9 @@ class Trace extends PerformanceAttributes { /// Using ```await``` with this method is only necessary when accurate timing /// is relevant. Future start() { + if (_hasStarted || _hasStopped) return Future.value(null); + + _hasStarted = true; return channel.invokeMethod('$Trace#start'); } @@ -49,6 +60,9 @@ class Trace extends PerformanceAttributes { /// /// Not necessary to use ```await``` with this method. Future stop() { + if (_hasStopped) return Future.value(null); + + _hasStopped = true; return channel.invokeMethod('$Trace#stop'); } @@ -58,6 +72,11 @@ class Trace extends PerformanceAttributes { /// not been started or has already been stopped, returns immediately without /// taking action. Future incrementMetric(String name, int value) { + if (!_hasStarted || _hasStopped || _metrics[name] == null) { + return Future.value(null); + } + + _metrics[name] += value; return channel.invokeMethod( '$Trace#incrementMetric', {'name': name, 'value': value}, @@ -70,6 +89,9 @@ class Trace extends PerformanceAttributes { /// If the trace has not been started or has already been stopped, returns /// immediately without taking action. Future putMetric(String name, int value) { + if (!_hasStarted || _hasStopped) return Future.value(null); + + _metrics[name] = value; return channel.invokeMethod( '$Trace#putMetric', {'name': name, 'value': value}, @@ -81,6 +103,10 @@ class Trace extends PerformanceAttributes { /// If a metric with the given name doesn't exist, it is NOT created and a 0 /// is returned. Future getMetric(String name) { + if (_hasStopped) { + return Future.value(_metrics[name] ?? 0); + } + return channel.invokeMethod( '$Trace#getMetric', {'name': name}, diff --git a/packages/firebase_performance/test/firebase_performance_test.dart b/packages/firebase_performance/test/firebase_performance_test.dart index 42b8f67e7c24..2dd5fe122998 100644 --- a/packages/firebase_performance/test/firebase_performance_test.dart +++ b/packages/firebase_performance/test/firebase_performance_test.dart @@ -157,16 +157,18 @@ void main() { test('incrementMetric', () { final String name = 'counter1'; final int value = 45; + final int increment = 3; - testTrace.incrementMetric(name, value); + testTrace.start(); + testTrace.putMetric(name, value); + traceLog.clear(); + + testTrace.incrementMetric(name, increment); expect(traceLog, [ isMethodCall( 'Trace#incrementMetric', - arguments: { - 'name': name, - 'value': value, - }, + arguments: {'name': name, 'value': increment}, ), ]); }); @@ -212,7 +214,7 @@ void main() { }); group('$PerformanceAttributes', () { - final PerformanceAttributes attributes = MockPerformanceAttributes(); + Trace attributeTrace; final List attributeLog = []; final Map getAttributesResult = { 'a1': 'hello', @@ -220,7 +222,8 @@ void main() { }; setUp(() { - MockPerformanceAttributes._channel + attributeTrace = performance.newTrace('trace'); + attributeTrace.channel .setMockMethodCallHandler((MethodCall methodCall) async { attributeLog.add(methodCall); if (methodCall.method == 'PerformanceAttributes#getAttributes') { @@ -229,13 +232,16 @@ void main() { return null; }); + + attributeTrace.start(); attributeLog.clear(); }); test('putAttribute', () { final String attribute = 'attr1'; final String value = 'apple'; - attributes.putAttribute(attribute, value); + + attributeTrace.putAttribute(attribute, value); expect(attributeLog, [ isMethodCall( @@ -250,7 +256,7 @@ void main() { test('removeAttribute', () { final String attribute = 'attr1'; - attributes.removeAttribute(attribute); + attributeTrace.removeAttribute(attribute); expect(attributeLog, [ isMethodCall( @@ -261,7 +267,7 @@ void main() { }); test('getAttributes', () async { - final Map result = await attributes.getAttributes(); + final Map result = await attributeTrace.getAttributes(); expect(attributeLog, [ isMethodCall( @@ -275,10 +281,3 @@ void main() { }); }); } - -class MockPerformanceAttributes extends PerformanceAttributes { - static MethodChannel _channel = const MethodChannel('testMethodChannel'); - - @override - MethodChannel get methodChannel => _channel; -} From 849d62566aa2cb3246acff8a7d14ca008a24b8c2 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 24 Apr 2019 11:46:02 -0700 Subject: [PATCH 08/13] Comments/Testings/Variables/Misc --- .../test_driver/firebase_performance.dart | 3 ++ .../lib/src/firebase_performance.dart | 11 +++++ .../lib/src/http_metric.dart | 47 ++++++++++++++++--- .../lib/src/performance_attributes.dart | 11 +++-- .../firebase_performance/lib/src/trace.dart | 26 +++++----- 5 files changed, 71 insertions(+), 27 deletions(-) diff --git a/packages/firebase_performance/example/test_driver/firebase_performance.dart b/packages/firebase_performance/example/test_driver/firebase_performance.dart index fcabfe11f239..295a5da94ad2 100644 --- a/packages/firebase_performance/example/test_driver/firebase_performance.dart +++ b/packages/firebase_performance/example/test_driver/firebase_performance.dart @@ -25,6 +25,8 @@ void main() { expect(disabled, isFalse); }); + // TODO(bparrishMines): Rewrite integration test when iOS portion is written. + /* test('metric', () async { final Trace trace = performance.newTrace('test'); trace.putAttribute('testAttribute', 'foo'); @@ -37,5 +39,6 @@ void main() { expect(trace.getAttribute('testAttribute2'), null); expect(trace.getAttribute('testMetric'), null); }); + */ }); } diff --git a/packages/firebase_performance/lib/src/firebase_performance.dart b/packages/firebase_performance/lib/src/firebase_performance.dart index d4843dcf245a..9a74c3d3632d 100644 --- a/packages/firebase_performance/lib/src/firebase_performance.dart +++ b/packages/firebase_performance/lib/src/firebase_performance.dart @@ -79,4 +79,15 @@ class FirebasePerformance { final MethodChannel channel = MethodChannel(channelName); return HttpMetric._(channel); } + + /// Creates a [Trace] object with given [name] and starts the trace. + /// + /// The [name] requires no leading or trailing whitespace, no leading + /// underscore _ character, max length of [Trace.maxTraceNameLength] + /// characters. + static Future startTrace(String name) async { + final Trace trace = instance.newTrace(name); + await trace.start(); + return trace; + } } diff --git a/packages/firebase_performance/lib/src/http_metric.dart b/packages/firebase_performance/lib/src/http_metric.dart index c7669571b5c1..12ec1dd895f8 100644 --- a/packages/firebase_performance/lib/src/http_metric.dart +++ b/packages/firebase_performance/lib/src/http_metric.dart @@ -18,22 +18,41 @@ part of firebase_performance; class HttpMetric extends PerformanceAttributes { HttpMetric._(this.channel); - @visibleForTesting - final MethodChannel channel; - @override bool _hasStarted = false; @override bool _hasStopped = false; + int _httpResponseCode; + int _requestPayloadSize; + String _responseContentType; + int _responsePayloadSize; + + @visibleForTesting @override - MethodChannel get methodChannel => channel; + final MethodChannel channel; + + /// HttpResponse code of the request. + int get httpResponseCode => _httpResponseCode; + + /// Size of the request payload. + int get requestPayloadSize => _requestPayloadSize; + + /// Content type of the response such as text/html, application/json, etc... + String get responseContentType => _responseContentType; + + /// Size of the response payload. + int get responsePayloadSize => _responsePayloadSize; /// HttpResponse code of the request. + /// + /// If the [HttpMetric] has already been stopped, returns immediately without + /// taking action. set httpResponseCode(int httpResponseCode) { if (_hasStopped) return; + _httpResponseCode = httpResponseCode; channel.invokeMethod( '$HttpMetric#httpResponseCode', httpResponseCode, @@ -41,9 +60,13 @@ class HttpMetric extends PerformanceAttributes { } /// Size of the request payload. + /// + /// If the [HttpMetric] has already been stopped, returns immediately without + /// taking action. set requestPayloadSize(int requestPayloadSize) { if (_hasStopped) return; + _requestPayloadSize = requestPayloadSize; channel.invokeMethod( '$HttpMetric#requestPayloadSize', requestPayloadSize, @@ -51,9 +74,13 @@ class HttpMetric extends PerformanceAttributes { } /// Content type of the response such as text/html, application/json, etc... + /// + /// If the [HttpMetric] has already been stopped, returns immediately without + /// taking action. set responseContentType(String responseContentType) { if (_hasStopped) return; + _responseContentType = responseContentType; channel.invokeMethod( '$HttpMetric#responseContentType', responseContentType, @@ -61,9 +88,13 @@ class HttpMetric extends PerformanceAttributes { } /// Size of the response payload. + /// + /// If the [HttpMetric] has already been stopped, returns immediately without + /// taking action. set responsePayloadSize(int responsePayloadSize) { if (_hasStopped) return; + _responsePayloadSize = responsePayloadSize; channel.invokeMethod( '$HttpMetric#responsePayloadSize', responsePayloadSize, @@ -72,10 +103,12 @@ class HttpMetric extends PerformanceAttributes { /// Starts this [HttpMetric]. /// - /// Using ```await``` with this method is only necessary when accurate timing + /// Can only be called once. + /// + /// Using `await` with this method is only necessary when accurate timing /// is relevant. Future start() { - if (_hasStarted || _hasStopped) return Future.value(null); + if (_hasStopped) return Future.value(null); _hasStarted = true; return channel.invokeMethod('$HttpMetric#start'); @@ -88,7 +121,7 @@ class HttpMetric extends PerformanceAttributes { /// called. You can confirm that Performance Monitoring results appear in the /// Firebase console. Results should appear within 12 hours. /// - /// Not necessary to use ```await``` with this method. + /// Not necessary to use `await` with this method. Future stop() { if (_hasStopped) return Future.value(null); diff --git a/packages/firebase_performance/lib/src/performance_attributes.dart b/packages/firebase_performance/lib/src/performance_attributes.dart index 09411e2d9079..de2f6452c41d 100644 --- a/packages/firebase_performance/lib/src/performance_attributes.dart +++ b/packages/firebase_performance/lib/src/performance_attributes.dart @@ -17,11 +17,12 @@ abstract class PerformanceAttributes { final Map _attributes = {}; - @visibleForTesting - MethodChannel get methodChannel; bool get _hasStarted; bool get _hasStopped; + @visibleForTesting + MethodChannel get channel; + /// Sets a String [value] for the specified [attribute]. /// /// Updates the value of the attribute if the attribute already exists. @@ -41,7 +42,7 @@ abstract class PerformanceAttributes { } _attributes[attribute] = value; - return methodChannel.invokeMethod( + return channel.invokeMethod( '$PerformanceAttributes#putAttribute', {'attribute': attribute, 'value': value}, ); @@ -52,7 +53,7 @@ abstract class PerformanceAttributes { if (!_hasStarted || _hasStopped) return Future.value(null); _attributes.remove(attribute); - return methodChannel.invokeMethod( + return channel.invokeMethod( '$PerformanceAttributes#removeAttribute', attribute, ); @@ -66,7 +67,7 @@ abstract class PerformanceAttributes { )); } - return methodChannel.invokeMapMethod( + return channel.invokeMapMethod( '$PerformanceAttributes#getAttributes', ); } diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index fc406199f900..484e2e3fba37 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -24,9 +24,6 @@ class Trace extends PerformanceAttributes { /// Maximum allowed length of the name of a [Trace]. static const int maxTraceNameLength = 100; - @visibleForTesting - final MethodChannel channel; - final Map _metrics = {}; @override @@ -35,17 +32,18 @@ class Trace extends PerformanceAttributes { @override bool _hasStopped = false; + @visibleForTesting @override - MethodChannel get methodChannel => channel; + final MethodChannel channel; /// Starts this [Trace]. /// /// Can only be called once. /// - /// Using ```await``` with this method is only necessary when accurate timing + /// Using `await` with this method is only necessary when accurate timing /// is relevant. Future start() { - if (_hasStarted || _hasStopped) return Future.value(null); + if (_hasStopped) return Future.value(null); _hasStarted = true; return channel.invokeMethod('$Trace#start'); @@ -58,7 +56,7 @@ class Trace extends PerformanceAttributes { /// called. You can confirm that Performance Monitoring results appear in the /// Firebase console. Results should appear within 12 hours. /// - /// Not necessary to use ```await``` with this method. + /// Not necessary to use `await` with this method. Future stop() { if (_hasStopped) return Future.value(null); @@ -66,9 +64,9 @@ class Trace extends PerformanceAttributes { return channel.invokeMethod('$Trace#stop'); } - /// Increments the metric with the given name. + /// Increments the metric with the given [name]. /// - /// If the metric does not exist, a new one will be created. If the trace has + /// If the metric does not exist, a new one will be created. If the [Trace] has /// not been started or has already been stopped, returns immediately without /// taking action. Future incrementMetric(String name, int value) { @@ -83,10 +81,10 @@ class Trace extends PerformanceAttributes { ); } - /// Sets the value of the metric with the given name. + /// Sets the [value] of the metric with the given [name]. /// /// If a metric with the given name doesn't exist, a new one will be created. - /// If the trace has not been started or has already been stopped, returns + /// If the [Trace] has not been started or has already been stopped, returns /// immediately without taking action. Future putMetric(String name, int value) { if (!_hasStarted || _hasStopped) return Future.value(null); @@ -98,14 +96,12 @@ class Trace extends PerformanceAttributes { ); } - /// Gets the value of the metric with the given name. + /// Gets the value of the metric with the given [name]. /// /// If a metric with the given name doesn't exist, it is NOT created and a 0 /// is returned. Future getMetric(String name) { - if (_hasStopped) { - return Future.value(_metrics[name] ?? 0); - } + if (_hasStopped) return Future.value(_metrics[name] ?? 0); return channel.invokeMethod( '$Trace#getMetric', From b08ad05bb12f46165f4b0f569f518fb2acca4a06 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 24 Apr 2019 12:08:26 -0700 Subject: [PATCH 09/13] Change putMetric to setMetric to match iOS API. Also add name variable --- .../lib/src/firebase_performance.dart | 2 +- packages/firebase_performance/lib/src/trace.dart | 9 ++++++--- .../test/firebase_performance_test.dart | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/firebase_performance/lib/src/firebase_performance.dart b/packages/firebase_performance/lib/src/firebase_performance.dart index 9a74c3d3632d..571e6b8063bd 100644 --- a/packages/firebase_performance/lib/src/firebase_performance.dart +++ b/packages/firebase_performance/lib/src/firebase_performance.dart @@ -59,7 +59,7 @@ class FirebasePerformance { ); final MethodChannel channel = MethodChannel(channelName); - return Trace._(channel); + return Trace._(channel, name); } /// Creates [HttpMetric] for collecting performance for one request/response. diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index 484e2e3fba37..20e240385eb7 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -19,7 +19,7 @@ part of firebase_performance; /// You can confirm that Performance Monitoring results appear in the Firebase /// console. Results should appear within 12 hours. class Trace extends PerformanceAttributes { - Trace._(this.channel); + Trace._(this.channel, this.name); /// Maximum allowed length of the name of a [Trace]. static const int maxTraceNameLength = 100; @@ -36,6 +36,9 @@ class Trace extends PerformanceAttributes { @override final MethodChannel channel; + /// Name representing this [Trace] on the Firebase Console. + final String name; + /// Starts this [Trace]. /// /// Can only be called once. @@ -86,12 +89,12 @@ class Trace extends PerformanceAttributes { /// If a metric with the given name doesn't exist, a new one will be created. /// If the [Trace] has not been started or has already been stopped, returns /// immediately without taking action. - Future putMetric(String name, int value) { + Future setMetric(String name, int value) { if (!_hasStarted || _hasStopped) return Future.value(null); _metrics[name] = value; return channel.invokeMethod( - '$Trace#putMetric', + '$Trace#setMetric', {'name': name, 'value': value}, ); } diff --git a/packages/firebase_performance/test/firebase_performance_test.dart b/packages/firebase_performance/test/firebase_performance_test.dart index 2dd5fe122998..7ce36bb65294 100644 --- a/packages/firebase_performance/test/firebase_performance_test.dart +++ b/packages/firebase_performance/test/firebase_performance_test.dart @@ -160,7 +160,7 @@ void main() { final int increment = 3; testTrace.start(); - testTrace.putMetric(name, value); + testTrace.setMetric(name, value); traceLog.clear(); testTrace.incrementMetric(name, increment); From 7800e5d0d616ca971089598bd49b6827eb745fd3 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Mon, 29 Apr 2019 22:41:17 -0700 Subject: [PATCH 10/13] 3rd redesign :( --- .../lib/src/firebase_performance.dart | 40 +++++++++------- .../lib/src/http_metric.dart | 46 +++++++++++++------ .../lib/src/performance_attributes.dart | 18 +++++--- .../firebase_performance/lib/src/trace.dart | 27 ++++++----- 4 files changed, 83 insertions(+), 48 deletions(-) diff --git a/packages/firebase_performance/lib/src/firebase_performance.dart b/packages/firebase_performance/lib/src/firebase_performance.dart index 571e6b8063bd..e2498ec172cb 100644 --- a/packages/firebase_performance/lib/src/firebase_performance.dart +++ b/packages/firebase_performance/lib/src/firebase_performance.dart @@ -11,16 +11,24 @@ enum HttpMethod { Connect, Delete, Get, Head, Options, Patch, Post, Put, Trace } /// /// You can get an instance by calling [FirebasePerformance.instance]. class FirebasePerformance { - FirebasePerformance._(); + FirebasePerformance._(this._handle) { + channel.invokeMethod( + 'FirebasePerformance#instance', + {'handle': _handle}, + ); + } + + static int _nextHandle = 0; + + final int _handle; @visibleForTesting static const MethodChannel channel = MethodChannel('plugins.flutter.io/firebase_performance'); /// Singleton of [FirebasePerformance]. - static final FirebasePerformance instance = FirebasePerformance._(); - - static int _channelCount = 0; + static final FirebasePerformance instance = + FirebasePerformance._(_nextHandle++); /// Determines whether performance monitoring is enabled or disabled. /// @@ -29,7 +37,8 @@ class FirebasePerformance { /// does not reflect whether instrumentation is enabled/disabled. Future isPerformanceCollectionEnabled() { return channel.invokeMethod( - 'FirebasePerformance#isPerformanceCollectionEnabled', + '$FirebasePerformance#isPerformanceCollectionEnabled', + {'handle': _handle}, ); } @@ -39,8 +48,8 @@ class FirebasePerformance { /// application. By default, performance monitoring is enabled. Future setPerformanceCollectionEnabled(bool enable) { return channel.invokeMethod( - 'FirebasePerformance#setPerformanceCollectionEnabled', - enable, + '$FirebasePerformance#setPerformanceCollectionEnabled', + {'handle': _handle, 'enable': enable}, ); } @@ -50,34 +59,31 @@ class FirebasePerformance { /// underscore _ character, and max length of [Trace.maxTraceNameLength] /// characters. Trace newTrace(String name) { - final String channelName = - '${FirebasePerformance.channel.name}/$Trace/${_channelCount++}'; + final int handle = _nextHandle++; FirebasePerformance.channel.invokeMethod( '$FirebasePerformance#newTrace', - {'channelName': channelName, 'traceName': name}, + {'handle': _handle, 'traceHandle': handle, 'name': name}, ); - final MethodChannel channel = MethodChannel(channelName); - return Trace._(channel, name); + return Trace._(handle, name); } /// Creates [HttpMetric] for collecting performance for one request/response. HttpMetric newHttpMetric(String url, HttpMethod httpMethod) { - final String channelName = - '${FirebasePerformance.channel.name}/$HttpMetric/${_channelCount++}'; + final int handle = _nextHandle++; FirebasePerformance.channel.invokeMethod( '$FirebasePerformance#newHttpMetric', { - 'channelName': channelName, + 'handle': _handle, + 'httpMetricHandle': handle, 'url': url, 'httpMethod': httpMethod.toString(), }, ); - final MethodChannel channel = MethodChannel(channelName); - return HttpMetric._(channel); + return HttpMetric._(handle, url, httpMethod); } /// Creates a [Trace] object with given [name] and starts the trace. diff --git a/packages/firebase_performance/lib/src/http_metric.dart b/packages/firebase_performance/lib/src/http_metric.dart index 12ec1dd895f8..a9f54830790b 100644 --- a/packages/firebase_performance/lib/src/http_metric.dart +++ b/packages/firebase_performance/lib/src/http_metric.dart @@ -16,7 +16,10 @@ part of firebase_performance; /// You can confirm that Performance Monitoring results appear in the Firebase /// console. Results should appear within 12 hours. class HttpMetric extends PerformanceAttributes { - HttpMetric._(this.channel); + HttpMetric._(this._handle, this.url, this.httpMethod); + + final String url; + final HttpMethod httpMethod; @override bool _hasStarted = false; @@ -29,9 +32,8 @@ class HttpMetric extends PerformanceAttributes { String _responseContentType; int _responsePayloadSize; - @visibleForTesting @override - final MethodChannel channel; + final int _handle; /// HttpResponse code of the request. int get httpResponseCode => _httpResponseCode; @@ -53,9 +55,12 @@ class HttpMetric extends PerformanceAttributes { if (_hasStopped) return; _httpResponseCode = httpResponseCode; - channel.invokeMethod( + FirebasePerformance.channel.invokeMethod( '$HttpMetric#httpResponseCode', - httpResponseCode, + { + 'handle': _handle, + 'httpResponseCode': httpResponseCode, + }, ); } @@ -67,9 +72,12 @@ class HttpMetric extends PerformanceAttributes { if (_hasStopped) return; _requestPayloadSize = requestPayloadSize; - channel.invokeMethod( + FirebasePerformance.channel.invokeMethod( '$HttpMetric#requestPayloadSize', - requestPayloadSize, + { + 'handle': _handle, + 'requestPayloadSize': requestPayloadSize, + }, ); } @@ -81,9 +89,12 @@ class HttpMetric extends PerformanceAttributes { if (_hasStopped) return; _responseContentType = responseContentType; - channel.invokeMethod( + FirebasePerformance.channel.invokeMethod( '$HttpMetric#responseContentType', - responseContentType, + { + 'handle': _handle, + 'responseContentType': responseContentType, + }, ); } @@ -95,9 +106,12 @@ class HttpMetric extends PerformanceAttributes { if (_hasStopped) return; _responsePayloadSize = responsePayloadSize; - channel.invokeMethod( + FirebasePerformance.channel.invokeMethod( '$HttpMetric#responsePayloadSize', - responsePayloadSize, + { + 'handle': _handle, + 'responsePayloadSize': responsePayloadSize, + }, ); } @@ -111,7 +125,10 @@ class HttpMetric extends PerformanceAttributes { if (_hasStopped) return Future.value(null); _hasStarted = true; - return channel.invokeMethod('$HttpMetric#start'); + return FirebasePerformance.channel.invokeMethod( + '$HttpMetric#start', + {'handle': _handle}, + ); } /// Stops this [HttpMetric]. @@ -126,6 +143,9 @@ class HttpMetric extends PerformanceAttributes { if (_hasStopped) return Future.value(null); _hasStopped = true; - return channel.invokeMethod('$HttpMetric#stop'); + return FirebasePerformance.channel.invokeMethod( + '$HttpMetric#stop', + {'handle': _handle}, + ); } } diff --git a/packages/firebase_performance/lib/src/performance_attributes.dart b/packages/firebase_performance/lib/src/performance_attributes.dart index de2f6452c41d..c12abb499655 100644 --- a/packages/firebase_performance/lib/src/performance_attributes.dart +++ b/packages/firebase_performance/lib/src/performance_attributes.dart @@ -20,8 +20,7 @@ abstract class PerformanceAttributes { bool get _hasStarted; bool get _hasStopped; - @visibleForTesting - MethodChannel get channel; + int get _handle; /// Sets a String [value] for the specified [attribute]. /// @@ -42,9 +41,13 @@ abstract class PerformanceAttributes { } _attributes[attribute] = value; - return channel.invokeMethod( + return FirebasePerformance.channel.invokeMethod( '$PerformanceAttributes#putAttribute', - {'attribute': attribute, 'value': value}, + { + 'handle': _handle, + 'attribute': attribute, + 'value': value, + }, ); } @@ -53,9 +56,9 @@ abstract class PerformanceAttributes { if (!_hasStarted || _hasStopped) return Future.value(null); _attributes.remove(attribute); - return channel.invokeMethod( + return FirebasePerformance.channel.invokeMethod( '$PerformanceAttributes#removeAttribute', - attribute, + {'handle': _handle, 'attribute': attribute}, ); } @@ -67,8 +70,9 @@ abstract class PerformanceAttributes { )); } - return channel.invokeMapMethod( + return FirebasePerformance.channel.invokeMapMethod( '$PerformanceAttributes#getAttributes', + {'handle': _handle}, ); } } diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index 20e240385eb7..5f8a98ad0151 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -19,7 +19,7 @@ part of firebase_performance; /// You can confirm that Performance Monitoring results appear in the Firebase /// console. Results should appear within 12 hours. class Trace extends PerformanceAttributes { - Trace._(this.channel, this.name); + Trace._(this._handle, this.name); /// Maximum allowed length of the name of a [Trace]. static const int maxTraceNameLength = 100; @@ -32,9 +32,8 @@ class Trace extends PerformanceAttributes { @override bool _hasStopped = false; - @visibleForTesting @override - final MethodChannel channel; + final int _handle; /// Name representing this [Trace] on the Firebase Console. final String name; @@ -49,7 +48,10 @@ class Trace extends PerformanceAttributes { if (_hasStopped) return Future.value(null); _hasStarted = true; - return channel.invokeMethod('$Trace#start'); + return FirebasePerformance.channel.invokeMethod( + '$Trace#start', + {'handle': _handle}, + ); } /// Stops this [Trace]. @@ -64,7 +66,10 @@ class Trace extends PerformanceAttributes { if (_hasStopped) return Future.value(null); _hasStopped = true; - return channel.invokeMethod('$Trace#stop'); + return FirebasePerformance.channel.invokeMethod( + '$Trace#stop', + {'handle': _handle}, + ); } /// Increments the metric with the given [name]. @@ -78,9 +83,9 @@ class Trace extends PerformanceAttributes { } _metrics[name] += value; - return channel.invokeMethod( + return FirebasePerformance.channel.invokeMethod( '$Trace#incrementMetric', - {'name': name, 'value': value}, + {'handle': _handle, 'name': name, 'value': value}, ); } @@ -93,9 +98,9 @@ class Trace extends PerformanceAttributes { if (!_hasStarted || _hasStopped) return Future.value(null); _metrics[name] = value; - return channel.invokeMethod( + return FirebasePerformance.channel.invokeMethod( '$Trace#setMetric', - {'name': name, 'value': value}, + {'handle': _handle, 'name': name, 'value': value}, ); } @@ -106,9 +111,9 @@ class Trace extends PerformanceAttributes { Future getMetric(String name) { if (_hasStopped) return Future.value(_metrics[name] ?? 0); - return channel.invokeMethod( + return FirebasePerformance.channel.invokeMethod( '$Trace#getMetric', - {'name': name}, + {'handle': _handle, 'name': name}, ); } } From 9d8ff822d2d5a132d570f08a30c94f21a4b9745e Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 1 May 2019 13:56:15 -0700 Subject: [PATCH 11/13] Update testing --- .../lib/src/performance_attributes.dart | 18 +- .../firebase_performance/lib/src/trace.dart | 3 +- .../test/firebase_performance_test.dart | 182 ++++++++++-------- 3 files changed, 115 insertions(+), 88 deletions(-) diff --git a/packages/firebase_performance/lib/src/performance_attributes.dart b/packages/firebase_performance/lib/src/performance_attributes.dart index c12abb499655..119567a1eaf0 100644 --- a/packages/firebase_performance/lib/src/performance_attributes.dart +++ b/packages/firebase_performance/lib/src/performance_attributes.dart @@ -22,7 +22,7 @@ abstract class PerformanceAttributes { int get _handle; - /// Sets a String [value] for the specified [attribute]. + /// Sets a String [value] for the specified attribute with [name]. /// /// Updates the value of the attribute if the attribute already exists. /// The maximum number of attributes that can be added are @@ -31,34 +31,34 @@ abstract class PerformanceAttributes { /// Name of the attribute has max length of [maxAttributeKeyLength] /// characters. Value of the attribute has max length of /// [maxAttributeValueLength] characters. - Future putAttribute(String attribute, String value) { + Future putAttribute(String name, String value) { if (!_hasStarted || _hasStopped || - attribute.length > maxAttributeKeyLength || + name.length > maxAttributeKeyLength || value.length > maxAttributeValueLength || _attributes.length == 5) { return Future.value(null); } - _attributes[attribute] = value; + _attributes[name] = value; return FirebasePerformance.channel.invokeMethod( '$PerformanceAttributes#putAttribute', { 'handle': _handle, - 'attribute': attribute, + 'name': name, 'value': value, }, ); } - /// Removes an already added [attribute]. - Future removeAttribute(String attribute) { + /// Removes an already added attribute with [name]. + Future removeAttribute(String name) { if (!_hasStarted || _hasStopped) return Future.value(null); - _attributes.remove(attribute); + _attributes.remove(name); return FirebasePerformance.channel.invokeMethod( '$PerformanceAttributes#removeAttribute', - {'handle': _handle, 'attribute': attribute}, + {'handle': _handle, 'name': name}, ); } diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index 5f8a98ad0151..f77e0f7a3683 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -78,10 +78,11 @@ class Trace extends PerformanceAttributes { /// not been started or has already been stopped, returns immediately without /// taking action. Future incrementMetric(String name, int value) { - if (!_hasStarted || _hasStopped || _metrics[name] == null) { + if (!_hasStarted || _hasStopped) { return Future.value(null); } + _metrics.putIfAbsent(name, () => 0); _metrics[name] += value; return FirebasePerformance.channel.invokeMethod( '$Trace#incrementMetric', diff --git a/packages/firebase_performance/test/firebase_performance_test.dart b/packages/firebase_performance/test/firebase_performance_test.dart index 7ce36bb65294..c2dbd1997c0a 100644 --- a/packages/firebase_performance/test/firebase_performance_test.dart +++ b/packages/firebase_performance/test/firebase_performance_test.dart @@ -9,10 +9,13 @@ import 'package:flutter_test/flutter_test.dart'; void main() { group('$FirebasePerformance', () { - final FirebasePerformance performance = FirebasePerformance.instance; + FirebasePerformance performance; final List log = []; bool isPerformanceCollectionEnabledResult; + int firebasePerformanceHandle; + int nextHandle = 0; + setUp(() { FirebasePerformance.channel .setMockMethodCallHandler((MethodCall methodCall) async { @@ -27,6 +30,19 @@ void main() { log.clear(); }); + test('instance', () { + firebasePerformanceHandle = nextHandle++; + + performance = FirebasePerformance.instance; + + expect(log, [ + isMethodCall( + 'FirebasePerformance#instance', + arguments: {'handle': firebasePerformanceHandle}, + ), + ]); + }); + test('isPerformanceCollectionEnabled', () async { isPerformanceCollectionEnabledResult = true; final bool enabled = await performance.isPerformanceCollectionEnabled(); @@ -39,11 +55,11 @@ void main() { expect(log, [ isMethodCall( 'FirebasePerformance#isPerformanceCollectionEnabled', - arguments: null, + arguments: {'handle': firebasePerformanceHandle}, ), isMethodCall( 'FirebasePerformance#isPerformanceCollectionEnabled', - arguments: null, + arguments: {'handle': firebasePerformanceHandle}, ), ]); }); @@ -55,24 +71,31 @@ void main() { expect(log, [ isMethodCall( 'FirebasePerformance#setPerformanceCollectionEnabled', - arguments: true, + arguments: { + 'handle': firebasePerformanceHandle, + 'enable': true, + }, ), isMethodCall( 'FirebasePerformance#setPerformanceCollectionEnabled', - arguments: false, + arguments: { + 'handle': firebasePerformanceHandle, + 'enable': false, + }, ), ]); }); test('newTrace', () { - final Trace trace = performance.newTrace('test-trace'); + performance.newTrace('test-trace'); expect(log, [ isMethodCall( 'FirebasePerformance#newTrace', arguments: { - 'channelName': trace.channel.name, - 'traceName': 'test-trace', + 'handle': firebasePerformanceHandle, + 'traceHandle': nextHandle++, + 'name': 'test-trace', }, ), ]); @@ -80,17 +103,14 @@ void main() { test('newHttpMetric', () { final String url = 'https://google.com'; - - final HttpMetric metric = performance.newHttpMetric( - url, - HttpMethod.Connect, - ); + performance.newHttpMetric(url, HttpMethod.Connect); expect(log, [ isMethodCall( 'FirebasePerformance#newHttpMetric', arguments: { - 'channelName': metric.channel.name, + 'handle': firebasePerformanceHandle, + 'httpMetricHandle': nextHandle++, 'url': url, 'httpMethod': HttpMethod.Connect.toString(), }, @@ -102,16 +122,14 @@ void main() { final String url = 'https://google.com'; final HttpMethod method = HttpMethod.Connect; - final HttpMetric metric = performance.newHttpMetric( - 'https://google.com', - method, - ); + performance.newHttpMetric('https://google.com', method); expect(log, [ isMethodCall( 'FirebasePerformance#newHttpMetric', arguments: { - 'channelName': metric.channel.name, + 'handle': firebasePerformanceHandle, + 'httpMetricHandle': nextHandle++, 'url': url, 'httpMethod': method.toString(), }, @@ -121,54 +139,55 @@ void main() { group('$Trace', () { Trace testTrace; - final List traceLog = []; + int currentTestTraceHandle; setUp(() { testTrace = performance.newTrace('test'); - testTrace.channel - .setMockMethodCallHandler((MethodCall methodCall) async { - traceLog.add(methodCall); - switch (methodCall.method) { - case 'FirebasePerformance#isPerformanceCollectionEnabled': - return true; - default: - return null; - } - }); - traceLog.clear(); + currentTestTraceHandle = nextHandle++; + log.clear(); }); test('start', () { testTrace.start(); - expect(traceLog, [ - isMethodCall('Trace#start', arguments: null), + expect(log, [ + isMethodCall( + 'Trace#start', + arguments: {'handle': currentTestTraceHandle}, + ), ]); }); test('stop', () { + testTrace.start(); + log.clear(); + testTrace.stop(); - expect(traceLog, [ - isMethodCall('Trace#stop', arguments: null), + expect(log, [ + isMethodCall( + 'Trace#stop', + arguments: {'handle': currentTestTraceHandle}, + ), ]); }); test('incrementMetric', () { - final String name = 'counter1'; - final int value = 45; - final int increment = 3; - testTrace.start(); - testTrace.setMetric(name, value); - traceLog.clear(); + log.clear(); + final String name = 'metric1'; + final int increment = 3; testTrace.incrementMetric(name, increment); - expect(traceLog, [ + expect(log, [ isMethodCall( 'Trace#incrementMetric', - arguments: {'name': name, 'value': increment}, + arguments: { + 'handle': currentTestTraceHandle, + 'name': name, + 'value': increment, + }, ), ]); }); @@ -176,78 +195,82 @@ void main() { group('$HttpMetric', () { HttpMetric testMetric; - final List httpMetricLog = []; + int currentTestMetricHandle; setUp(() { testMetric = performance.newHttpMetric( 'https://google.com', HttpMethod.Get, ); - testMetric.channel - .setMockMethodCallHandler((MethodCall methodCall) async { - httpMetricLog.add(methodCall); - switch (methodCall.method) { - case 'FirebasePerformance#isPerformanceCollectionEnabled': - return true; - default: - return null; - } - }); - httpMetricLog.clear(); + currentTestMetricHandle = nextHandle++; + log.clear(); }); test('start', () { testMetric.start(); - expect(httpMetricLog, [ - isMethodCall('HttpMetric#start', arguments: null), + expect(log, [ + isMethodCall( + 'HttpMetric#start', + arguments: {'handle': currentTestMetricHandle}, + ), ]); }); test('stop', () { + testMetric.start(); + log.clear(); + testMetric.stop(); - expect(httpMetricLog, [ - isMethodCall('HttpMetric#stop', arguments: null), + expect(log, [ + isMethodCall( + 'HttpMetric#stop', + arguments: {'handle': currentTestMetricHandle}, + ), ]); }); }); group('$PerformanceAttributes', () { Trace attributeTrace; - final List attributeLog = []; + int currentTraceHandle; + final Map getAttributesResult = { 'a1': 'hello', 'a2': 'friend', }; setUp(() { - attributeTrace = performance.newTrace('trace'); - attributeTrace.channel + FirebasePerformance.channel .setMockMethodCallHandler((MethodCall methodCall) async { - attributeLog.add(methodCall); - if (methodCall.method == 'PerformanceAttributes#getAttributes') { - return getAttributesResult; + log.add(methodCall); + switch (methodCall.method) { + case 'PerformanceAttributes#getAttributes': + return getAttributesResult; + default: + return null; } - - return null; }); + attributeTrace = performance.newTrace('trace'); + currentTraceHandle = nextHandle++; attributeTrace.start(); - attributeLog.clear(); + log.clear(); }); test('putAttribute', () { - final String attribute = 'attr1'; + final String name = 'attr1'; final String value = 'apple'; - attributeTrace.putAttribute(attribute, value); + attributeTrace.putAttribute(name, value); - expect(attributeLog, [ + expect(log, [ isMethodCall( 'PerformanceAttributes#putAttribute', arguments: { - 'attribute': attribute, + 'handle': currentTraceHandle, + 'name': name, 'value': value, }, ), @@ -255,13 +278,16 @@ void main() { }); test('removeAttribute', () { - final String attribute = 'attr1'; - attributeTrace.removeAttribute(attribute); + final String name = 'attr1'; + attributeTrace.removeAttribute(name); - expect(attributeLog, [ + expect(log, [ isMethodCall( 'PerformanceAttributes#removeAttribute', - arguments: attribute, + arguments: { + 'handle': currentTraceHandle, + 'name': name, + }, ), ]); }); @@ -269,10 +295,10 @@ void main() { test('getAttributes', () async { final Map result = await attributeTrace.getAttributes(); - expect(attributeLog, [ + expect(log, [ isMethodCall( 'PerformanceAttributes#getAttributes', - arguments: null, + arguments: {'handle': currentTraceHandle}, ), ]); From d6f25191769e53543cb037815dd73b880d892d1e Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Wed, 1 May 2019 16:58:37 -0700 Subject: [PATCH 12/13] Temporarily remove integration tests --- packages/firebase_performance/example/lib/main.dart | 1 - .../example/test_driver/firebase_performance.dart | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/firebase_performance/example/lib/main.dart b/packages/firebase_performance/example/lib/main.dart index 61e1ae39b6e7..16ed5b4322ee 100644 --- a/packages/firebase_performance/example/lib/main.dart +++ b/packages/firebase_performance/example/lib/main.dart @@ -77,7 +77,6 @@ class _MyAppState extends State { }); final Trace trace = _performance.newTrace("test"); - trace.incrementMetric("metric1", 16); trace.putAttribute("favorite_color", "blue"); diff --git a/packages/firebase_performance/example/test_driver/firebase_performance.dart b/packages/firebase_performance/example/test_driver/firebase_performance.dart index 295a5da94ad2..352db529bd1b 100644 --- a/packages/firebase_performance/example/test_driver/firebase_performance.dart +++ b/packages/firebase_performance/example/test_driver/firebase_performance.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'package:flutter_driver/driver_extension.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:firebase_performance/firebase_performance.dart'; void main() { final Completer completer = Completer(); @@ -10,6 +9,8 @@ void main() { tearDownAll(() => completer.complete(null)); group('firebase_performance test driver', () { + // TODO(bparrishMines): Rewrite integration tests when iOS portion is written. + /* final FirebasePerformance performance = FirebasePerformance.instance; setUp(() async { @@ -25,8 +26,6 @@ void main() { expect(disabled, isFalse); }); - // TODO(bparrishMines): Rewrite integration test when iOS portion is written. - /* test('metric', () async { final Trace trace = performance.newTrace('test'); trace.putAttribute('testAttribute', 'foo'); From a04ef6ad7801a69e216398e425ede3c5098dc525 Mon Sep 17 00:00:00 2001 From: Maurice Parrish Date: Thu, 9 May 2019 13:37:58 -0700 Subject: [PATCH 13/13] Add note about leaking --- packages/firebase_performance/lib/src/http_metric.dart | 5 ++++- packages/firebase_performance/lib/src/trace.dart | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/firebase_performance/lib/src/http_metric.dart b/packages/firebase_performance/lib/src/http_metric.dart index a9f54830790b..c0b27bb41ce3 100644 --- a/packages/firebase_performance/lib/src/http_metric.dart +++ b/packages/firebase_performance/lib/src/http_metric.dart @@ -8,13 +8,16 @@ part of firebase_performance; /// /// It is possible to have more than one [HttpMetric] running at a time. /// Attributes can also be added to help measure performance related events. A -/// [HttpMetric] also measures the time between calling start() and stop(). +/// [HttpMetric] also measures the time between calling `start()` and `stop()`. /// /// Data collected is automatically sent to the associated Firebase console /// after stop() is called. /// /// You can confirm that Performance Monitoring results appear in the Firebase /// console. Results should appear within 12 hours. +/// +/// It is highly recommended that one always calls `start()` and `stop()` on +/// each created [HttpMetric] to avoid leaking on the platform side. class HttpMetric extends PerformanceAttributes { HttpMetric._(this._handle, this.url, this.httpMethod); diff --git a/packages/firebase_performance/lib/src/trace.dart b/packages/firebase_performance/lib/src/trace.dart index f77e0f7a3683..cf8e1fb01d3a 100644 --- a/packages/firebase_performance/lib/src/trace.dart +++ b/packages/firebase_performance/lib/src/trace.dart @@ -11,13 +11,16 @@ part of firebase_performance; /// possible to have more than one custom trace running at a time. Each custom /// trace can have multiple metrics and attributes added to help measure /// performance related events. A trace also measures the time between calling -/// start() and stop(). +/// `start()` and `stop()`. /// /// Data collected is automatically sent to the associated Firebase console /// after stop() is called. /// /// You can confirm that Performance Monitoring results appear in the Firebase /// console. Results should appear within 12 hours. +/// +/// It is highly recommended that one always calls `start()` and `stop()` on +/// each created [Trace] to not avoid leaking on the platform side. class Trace extends PerformanceAttributes { Trace._(this._handle, this.name);