| Index: pkg/analysis_server/test/performance/instrumentation_input_converter.dart
|
| diff --git a/pkg/analysis_server/test/performance/instrumentation_input_converter.dart b/pkg/analysis_server/test/performance/instrumentation_input_converter.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..4e027cf444117e6c6dc5cecba907a0542cd16e4c
|
| --- /dev/null
|
| +++ b/pkg/analysis_server/test/performance/instrumentation_input_converter.dart
|
| @@ -0,0 +1,139 @@
|
| +library input.transformer.instrumentation;
|
| +
|
| +import 'dart:convert';
|
| +
|
| +import 'package:logging/logging.dart';
|
| +
|
| +import 'operation.dart';
|
| +
|
| +final int COLON = ':'.codeUnitAt(0);
|
| +
|
| +/**
|
| + * [InstrumentationInputConverter] converts an instrumentation stream
|
| + * into a series of operations to be sent to the analysis server.
|
| + */
|
| +class InstrumentationInputConverter extends Converter<String, Operation> {
|
| + final Logger logger = new Logger('InstrumentationInputConverter');
|
| + final Set<String> _codesSeen = new Set<String>();
|
| + final Set<String> _methodsSeen = new Set<String>();
|
| + final Set<String> _eventsSeen = new Set<String>();
|
| +
|
| + @override
|
| + Operation convert(String line) {
|
| + try {
|
| + List<String> fields = _parseFields(line);
|
| + if (fields.length < 2) {
|
| + //return new InfoOperation('Ignored line:\n $line');
|
| + return null;
|
| + }
|
| + // int timeStamp = int.parse(fields[0], onError: (_) => -1);
|
| + String opCode = fields[1];
|
| + if (opCode == 'Req') {
|
| + return convertRequest(line, fields);
|
| + }
|
| + if (opCode == 'Noti') {
|
| + return convertNotification(fields);
|
| + }
|
| + if (opCode == 'Ver') {
|
| + // 1433195174666:Ver:1421765742287333878467:org.dartlang.dartplugin:0.0.0:1.7.0:1.11.0-edge.131698
|
| + return new StartServerOperation();
|
| + }
|
| + if (_codesSeen.add(opCode)) {
|
| + logger.log(Level.INFO, 'Ignored op code: $opCode\n $line');
|
| + }
|
| + return null;
|
| + } catch (e, s) {
|
| + throw 'Failed to parse line\n $line\n$e\n$s';
|
| + }
|
| + }
|
| +
|
| + /**
|
| + * Return an operation for the notification defined by [line] and [fields]
|
| + * or `null` if none.
|
| + */
|
| + Operation convertNotification(List<String> fields) {
|
| + //1433344448533:Noti:{"event"::"server.status","params"::{"analysis"::{"isAnalyzing"::false}}}
|
| + Map<String, dynamic> json = JSON.decode(fields[2]);
|
| + String event = json['event'];
|
| + if (event == 'server.status') {
|
| + Map<String, dynamic> params = json['params'];
|
| + if (params != null) {
|
| + Map<String, dynamic> analysis = params['analysis'];
|
| + if (analysis != null && analysis['isAnalyzing'] == false) {
|
| + return new WaitForAnalysisCompleteOperation();
|
| + }
|
| + }
|
| + }
|
| + if (event == 'server.connected') {
|
| + // Handled by the driver
|
| + return null;
|
| + }
|
| + if (_eventsSeen.add(event)) {
|
| + logger.log(Level.INFO, 'Ignored notification: $event');
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + /**
|
| + * Return an operation for the request defined by [line] and [fields]
|
| + * or `null` if none.
|
| + */
|
| + Operation convertRequest(String line, List<String> fields) {
|
| + Map<String, dynamic> json = JSON.decode(fields[2]);
|
| + String method = json['method'];
|
| + if (method == 'analysis.setAnalysisRoots') {
|
| + // 1433343174749:Req:{"id"::"3","method"::"analysis.setAnalysisRoots","params"::{"included"::["/usr/local/google/home/danrubel/work/git/dart_sdk/sdk/pkg/analysis_server","/usr/local/google/home/danrubel/work/git/dart_sdk/sdk/pkg/analyzer"],"excluded"::[],"packageRoots"::{}},"clientRequestTime"::1433343174702}
|
| + return new RequestOperation(json);
|
| + }
|
| + if (method == 'server.setSubscriptions') {
|
| + // 1433343174741:Req:{"id"::"1","method"::"server.setSubscriptions","params"::{"subscriptions"::["STATUS"]},"clientRequestTime"::1433343172679}
|
| + return new RequestOperation(json);
|
| + }
|
| + if (_methodsSeen.add(method)) {
|
| + logger.log(Level.INFO, 'Ignored request: $method\n $line');
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + /**
|
| + * Determine if the given line is from an instrumentation file.
|
| + * For example:
|
| + * `1433175833005:Ver:1421765742287333878467:org.dartlang.dartplugin:0.0.0:1.6.2:1.11.0-edge.131698`
|
| + */
|
| + static bool isFormat(String line) {
|
| + List<String> fields = _parseFields(line);
|
| + int timeStamp = int.parse(fields[0], onError: (_) => -1);
|
| + String opCode = fields[1];
|
| + return timeStamp > 0 && opCode == 'Ver';
|
| + }
|
| +
|
| + /**
|
| + * Extract fields from the given [line].
|
| + */
|
| + static List<String> _parseFields(String line) {
|
| + List<String> fields = new List<String>();
|
| + int index = 0;
|
| + StringBuffer sb = new StringBuffer();
|
| + while (index < line.length) {
|
| + int code = line.codeUnitAt(index);
|
| + if (code == COLON) {
|
| + // Embedded colons are doubled
|
| + int next = index + 1;
|
| + if (next < line.length && line.codeUnitAt(next) == COLON) {
|
| + sb.write(':');
|
| + ++index;
|
| + } else {
|
| + fields.add(sb.toString());
|
| + sb.clear();
|
| + }
|
| + } else {
|
| + sb.writeCharCode(code);
|
| + }
|
| + ++index;
|
| + }
|
| + if (sb.isNotEmpty) {
|
| + fields.add(sb.toString());
|
| + }
|
| + return fields;
|
| + }
|
| +}
|
|
|