Unverified Commit 8c902ad4 authored by Yegor's avatar Yegor Committed by GitHub

clear timeline events prior to starting a new action (#12984)

* clear timeline events prior to starting a new action

* trailing commas
parent e73d4061
...@@ -127,6 +127,7 @@ class FlutterDriver { ...@@ -127,6 +127,7 @@ class FlutterDriver {
static const String _kFlutterExtensionMethod = 'ext.flutter.driver'; static const String _kFlutterExtensionMethod = 'ext.flutter.driver';
static const String _kSetVMTimelineFlagsMethod = '_setVMTimelineFlags'; static const String _kSetVMTimelineFlagsMethod = '_setVMTimelineFlags';
static const String _kGetVMTimelineMethod = '_getVMTimeline'; static const String _kGetVMTimelineMethod = '_getVMTimeline';
static const String _kClearVMTimelineMethod = '_clearVMTimeline';
static int _nextDriverId = 0; static int _nextDriverId = 0;
...@@ -184,7 +185,7 @@ class FlutterDriver { ...@@ -184,7 +185,7 @@ class FlutterDriver {
final FlutterDriver driver = new FlutterDriver.connectedTo( final FlutterDriver driver = new FlutterDriver.connectedTo(
client, connection.peer, isolate, client, connection.peer, isolate,
printCommunication: printCommunication, printCommunication: printCommunication,
logCommunicationToFile: logCommunicationToFile logCommunicationToFile: logCommunicationToFile,
); );
// Attempts to resume the isolate, but does not crash if it fails because // Attempts to resume the isolate, but does not crash if it fails because
...@@ -327,13 +328,13 @@ class FlutterDriver { ...@@ -327,13 +328,13 @@ class FlutterDriver {
throw new DriverError( throw new DriverError(
'Failed to fulfill ${command.runtimeType}: Flutter application not responding', 'Failed to fulfill ${command.runtimeType}: Flutter application not responding',
error, error,
stackTrace stackTrace,
); );
} catch (error, stackTrace) { } catch (error, stackTrace) {
throw new DriverError( throw new DriverError(
'Failed to fulfill ${command.runtimeType} due to remote error', 'Failed to fulfill ${command.runtimeType} due to remote error',
error, error,
stackTrace stackTrace,
); );
} }
if (response['isError']) if (response['isError'])
...@@ -503,7 +504,10 @@ class FlutterDriver { ...@@ -503,7 +504,10 @@ class FlutterDriver {
} }
/// Starts recording performance traces. /// Starts recording performance traces.
Future<Null> startTracing({ List<TimelineStream> streams: _defaultStreams, Duration timeout: _kShortTimeout }) async { Future<Null> startTracing({
List<TimelineStream> streams: _defaultStreams,
Duration timeout: _kShortTimeout,
}) async {
assert(streams != null && streams.isNotEmpty); assert(streams != null && streams.isNotEmpty);
try { try {
await _peer.sendRequest(_kSetVMTimelineFlagsMethod, <String, String>{ await _peer.sendRequest(_kSetVMTimelineFlagsMethod, <String, String>{
...@@ -514,7 +518,7 @@ class FlutterDriver { ...@@ -514,7 +518,7 @@ class FlutterDriver {
throw new DriverError( throw new DriverError(
'Failed to start tracing due to remote error', 'Failed to start tracing due to remote error',
error, error,
stackTrace stackTrace,
); );
} }
} }
...@@ -530,7 +534,7 @@ class FlutterDriver { ...@@ -530,7 +534,7 @@ class FlutterDriver {
throw new DriverError( throw new DriverError(
'Failed to stop tracing due to remote error', 'Failed to stop tracing due to remote error',
error, error,
stackTrace stackTrace,
); );
} }
} }
...@@ -545,12 +549,38 @@ class FlutterDriver { ...@@ -545,12 +549,38 @@ class FlutterDriver {
/// ///
/// [streams] limits the recorded timeline event streams to only the ones /// [streams] limits the recorded timeline event streams to only the ones
/// listed. By default, all streams are recorded. /// listed. By default, all streams are recorded.
Future<Timeline> traceAction(Future<dynamic> action(), { List<TimelineStream> streams: _defaultStreams }) async { ///
/// If [retainPriorEvents] is true, retains events recorded prior to calling
/// [action]. Otherwise, prior events are cleared before calling [action]. By
/// default, prior events are cleared.
Future<Timeline> traceAction(
Future<dynamic> action(), {
List<TimelineStream> streams: _defaultStreams,
bool retainPriorEvents: false,
}) async {
if (!retainPriorEvents) {
await clearTimeline();
}
await startTracing(streams: streams); await startTracing(streams: streams);
await action(); await action();
return stopTracingAndDownloadTimeline(); return stopTracingAndDownloadTimeline();
} }
/// Clears all timeline events recorded up until now.
Future<Null> clearTimeline({ Duration timeout: _kShortTimeout }) async {
try {
await _peer
.sendRequest(_kClearVMTimelineMethod, <String, String>{})
.timeout(timeout);
} catch(error, stackTrace) {
throw new DriverError(
'Failed to clear event timeline due to remote error',
error,
stackTrace,
);
}
}
/// [action] will be executed with the frame sync mechanism disabled. /// [action] will be executed with the frame sync mechanism disabled.
/// ///
/// By default, Flutter Driver waits until there is no pending frame scheduled /// By default, Flutter Driver waits until there is no pending frame scheduled
......
...@@ -230,25 +230,45 @@ void main() { ...@@ -230,25 +230,45 @@ void main() {
}); });
}); });
group('clearTimeline', () {
test('clears timeline', () async {
bool clearWasCalled = false;
when(mockPeer.sendRequest('_clearVMTimeline', argThat(equals(<String, dynamic>{}))))
.thenAnswer((_) async {
clearWasCalled = true;
return null;
});
await driver.clearTimeline();
expect(clearWasCalled, isTrue);
});
});
group('traceAction', () { group('traceAction', () {
test('traces action', () async { List<String> log;
bool actionCalled = false;
bool startTracingCalled = false; setUp(() async {
bool stopTracingCalled = false; log = <String>[];
when(mockPeer.sendRequest('_clearVMTimeline', argThat(equals(<String, dynamic>{}))))
.thenAnswer((_) async {
log.add('clear');
return null;
});
when(mockPeer.sendRequest('_setVMTimelineFlags', argThat(equals(<String, dynamic>{'recordedStreams': '[all]'})))) when(mockPeer.sendRequest('_setVMTimelineFlags', argThat(equals(<String, dynamic>{'recordedStreams': '[all]'}))))
.thenAnswer((_) async { .thenAnswer((_) async {
startTracingCalled = true; log.add('startTracing');
return null; return null;
}); });
when(mockPeer.sendRequest('_setVMTimelineFlags', argThat(equals(<String, dynamic>{'recordedStreams': '[]'})))) when(mockPeer.sendRequest('_setVMTimelineFlags', argThat(equals(<String, dynamic>{'recordedStreams': '[]'}))))
.thenAnswer((_) async { .thenAnswer((_) async {
stopTracingCalled = true; log.add('stopTracing');
return null; return null;
}); });
when(mockPeer.sendRequest('_getVMTimeline')).thenAnswer((_) async { when(mockPeer.sendRequest('_getVMTimeline')).thenAnswer((_) async {
log.add('download');
return <String, dynamic> { return <String, dynamic> {
'traceEvents': <dynamic>[ 'traceEvents': <dynamic>[
<String, String>{ <String, String>{
...@@ -257,14 +277,34 @@ void main() { ...@@ -257,14 +277,34 @@ void main() {
], ],
}; };
}); });
});
test('without clearing timeline', () async {
final Timeline timeline = await driver.traceAction(() { final Timeline timeline = await driver.traceAction(() {
actionCalled = true; log.add('action');
}, retainPriorEvents: true);
expect(log, const <String>[
'startTracing',
'action',
'stopTracing',
'download',
]);
expect(timeline.events.single.name, 'test event');
}); });
expect(actionCalled, isTrue); test('with clearing timeline', () async {
expect(startTracingCalled, isTrue); final Timeline timeline = await driver.traceAction(() {
expect(stopTracingCalled, isTrue); log.add('action');
});
expect(log, const <String>[
'clear',
'startTracing',
'action',
'stopTracing',
'download',
]);
expect(timeline.events.single.name, 'test event'); expect(timeline.events.single.name, 'test event');
}); });
}); });
...@@ -304,7 +344,8 @@ void main() { ...@@ -304,7 +344,8 @@ void main() {
TimelineStream.dart, TimelineStream.dart,
TimelineStream.gc, TimelineStream.gc,
TimelineStream.compiler TimelineStream.compiler
]); ],
retainPriorEvents: true);
expect(actionCalled, isTrue); expect(actionCalled, isTrue);
expect(startTracingCalled, isTrue); expect(startTracingCalled, isTrue);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment