Migrate benchmark/integration/
R=brianwilkerson@google.com
Change-Id: I0dccc13831ec5aed82d33ee52ffeae1ad38c5b98
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194109
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/benchmark/integration/driver.dart b/pkg/analysis_server/benchmark/integration/driver.dart
index 6e831aa..9f40d74 100644
--- a/pkg/analysis_server/benchmark/integration/driver.dart
+++ b/pkg/analysis_server/benchmark/integration/driver.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart = 2.9
-
import 'dart:async';
import 'dart:math' show max, sqrt;
@@ -42,13 +40,13 @@
final Logger logger = Logger('Driver');
/// The diagnostic port for Analysis Server or `null` if none.
- final int diagnosticPort;
+ final int? diagnosticPort;
/// A flag indicating whether the server is running.
bool running = false;
@override
- Server server;
+ late Server server;
/// The results collected while running analysis server.
final Results results = Results();
@@ -65,7 +63,7 @@
/// Perform the given operation.
/// Return a [Future] that completes when the next operation can be performed,
/// or `null` if the next operation can be performed immediately
- Future perform(Operation op) {
+ Future<void>? perform(Operation op) {
return op.perform(this);
}
@@ -75,7 +73,7 @@
/// normal (non-error) response, the future will be completed with the
/// 'result' field from the response. If the server acknowledges the command
/// with an error response, the future will be completed with an error.
- Future<Map<String, dynamic>> send(
+ Future<Map<String, Object?>?> send(
String method, Map<String, dynamic> params) {
return server.send(method, params);
}
@@ -206,14 +204,17 @@
print('');
print('==================================================================');
print('');
- var keys = measurements.keys.toList()..sort();
- var keyLen = keys.fold(0, (int len, String key) => max(len, key.length));
+ var sortedEntries = measurements.entries.toList();
+ sortedEntries.sort((a, b) => a.key.compareTo(b.key));
+ var keyLen = sortedEntries
+ .map((e) => e.key)
+ .fold(0, (int len, String key) => max(len, key.length));
_printGroupHeader('Request/Response', keyLen);
var totalCount = 0;
var totalErrorCount = 0;
var totalUnexpectedResultCount = 0;
- for (var tag in keys) {
- var m = measurements[tag];
+ for (var entry in sortedEntries) {
+ var m = entry.value;
if (!m.notification) {
m.printSummary(keyLen);
totalCount += m.count;
@@ -225,8 +226,8 @@
keyLen, totalCount, totalErrorCount, totalUnexpectedResultCount);
print('');
_printGroupHeader('Notifications', keyLen);
- for (var tag in keys) {
- var m = measurements[tag];
+ for (var entry in sortedEntries) {
+ var m = entry.value;
if (m.notification) {
m.printSummary(keyLen);
}
@@ -252,7 +253,7 @@
}
void recordUnexpectedResults(String tag) {
- measurements[tag].recordUnexpectedResults();
+ measurements[tag]!.recordUnexpectedResults();
}
void _printGroupHeader(String groupName, int keyLen) {
diff --git a/pkg/analysis_server/benchmark/integration/input_converter.dart b/pkg/analysis_server/benchmark/integration/input_converter.dart
index e128456..0f86919 100644
--- a/pkg/analysis_server/benchmark/integration/input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/input_converter.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart = 2.9
-
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@@ -20,14 +18,14 @@
import 'operation.dart';
/// Common input converter superclass for sharing implementation.
-abstract class CommonInputConverter extends Converter<String, Operation> {
+abstract class CommonInputConverter extends Converter<String, Operation?> {
static final ERROR_PREFIX = 'Server responded with an error: ';
final Logger logger = Logger('InstrumentationInputConverter');
final Set<String> eventsSeen = <String>{};
/// A mapping from request/response id to request json
/// for those requests for which a response has not been processed.
- final Map<String, dynamic> requestMap = {};
+ final Map<String, Object?> requestMap = {};
/// A mapping from request/response id to a completer
/// for those requests for which a response has not been processed.
@@ -37,7 +35,7 @@
/// A mapping from request/response id to the actual response result
/// for those responses that have not been processed.
- final Map<String, dynamic> responseMap = {};
+ final Map<String, Object?> responseMap = {};
/// A mapping of current overlay content
/// parallel to what is in the analysis server
@@ -58,16 +56,18 @@
CommonInputConverter(this.tmpSrcDirPath, this.srcPathMap);
- Map<String, dynamic> asMap(dynamic value) => value as Map<String, dynamic>;
+ Map<String, Object?> asMap(dynamic value) => value as Map<String, Object?>;
+
+ Map<String, Object?>? asMap2(dynamic value) => value as Map<String, Object?>?;
/// Return an operation for the notification or `null` if none.
- Operation convertNotification(Map<String, dynamic> json) {
+ Operation? convertNotification(Map<String, dynamic> json) {
String event = json['event'];
if (event == SERVER_NOTIFICATION_STATUS) {
// {"event":"server.status","params":{"analysis":{"isAnalyzing":false}}}
- var params = asMap(json['params']);
+ var params = asMap2(json['params']);
if (params != null) {
- var analysis = asMap(params['analysis']);
+ var analysis = asMap2(params['analysis']);
if (analysis != null && analysis['isAnalyzing'] == false) {
return WaitForAnalysisCompleteOperation();
}
@@ -84,23 +84,20 @@
}
/// Return an operation for the request or `null` if none.
- Operation convertRequest(Map<String, dynamic> origJson) {
+ Operation convertRequest(Map<String, Object?> origJson) {
var json = asMap(translateSrcPaths(origJson));
- requestMap[json['id']] = json;
- String method = json['method'];
+ requestMap[json['id'] as String] = json;
+ var method = json['method'] as String;
// Sanity check operations that modify source
// to ensure that the operation is on source in temp space
if (method == ANALYSIS_REQUEST_UPDATE_CONTENT) {
// Track overlays in parallel with the analysis server
// so that when an overlay is removed, the file can be updated on disk
- var request = Request.fromJson(json);
+ var request = Request.fromJson(json)!;
var params = AnalysisUpdateContentParams.fromRequest(request);
params.files.forEach((String filePath, change) {
if (change is AddContentOverlay) {
var content = change.content;
- if (content == null) {
- throw 'expected new overlay content\n$json';
- }
overlays[filePath] = content;
} else if (change is ChangeContentOverlay) {
var content = overlays[filePath];
@@ -172,8 +169,9 @@
void processErrorResponse(String id, exception) {
var result = exception;
if (exception is UnimplementedError) {
- if (exception.message.startsWith(ERROR_PREFIX)) {
- result = json.decode(exception.message.substring(ERROR_PREFIX.length));
+ var message = exception.message;
+ if (message!.startsWith(ERROR_PREFIX)) {
+ result = json.decode(message.substring(ERROR_PREFIX.length));
}
}
processResponseResult(id, result);
@@ -186,7 +184,7 @@
/// Return a future that completes when the response is received
/// or `null` if the response has already been received
/// and the completer completed.
- Future processExpectedResponse(String id, Completer completer) {
+ Future<void>? processExpectedResponse(String id, Completer completer) {
if (responseMap.containsKey(id)) {
logger.log(Level.INFO, 'processing cached response $id');
completer.complete(responseMap.remove(id));
@@ -228,7 +226,7 @@
return result;
}
if (json is Map) {
- var result = <String, dynamic>{};
+ var result = <String, Object?>{};
json.forEach((origKey, value) {
result[translateSrcPaths(origKey)] = translateSrcPaths(value);
});
@@ -241,7 +239,7 @@
/// [InputConverter] converts an input stream
/// into a series of operations to be sent to the analysis server.
/// The input stream can be either an instrumentation or log file.
-class InputConverter extends Converter<String, Operation> {
+class InputConverter extends Converter<String, Operation?> {
final Logger logger = Logger('InputConverter');
/// A mapping of source path prefixes
@@ -259,7 +257,7 @@
/// The underlying converter used to translate lines into operations
/// or `null` if it has not yet been determined.
- Converter<String, Operation> converter;
+ Converter<String, Operation?>? converter;
/// [active] is `true` if converting lines to operations
/// or `false` if an exception has occurred.
@@ -268,10 +266,11 @@
InputConverter(this.tmpSrcDirPath, this.srcPathMap);
@override
- Operation convert(String line) {
+ Operation? convert(String line) {
if (!active) {
return null;
}
+ var converter = this.converter;
if (converter != null) {
try {
return converter.convert(line);
@@ -335,8 +334,8 @@
}
class _InputSink extends ChunkedConversionSink<String> {
- final Converter<String, Operation> converter;
- final Sink<Operation> outSink;
+ final Converter<String, Operation?> converter;
+ final Sink<Operation?> outSink;
_InputSink(this.converter, this.outSink);
diff --git a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
index 2cd8783..037c9b0 100644
--- a/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/instrumentation_input_converter.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart = 2.9
-
import 'dart:convert';
import 'package:analyzer/exception/exception.dart';
@@ -23,17 +21,18 @@
/// [readBuffer] holds the contents of the file being read from disk
/// as recorded in the instrumentation log
/// or `null` if not converting a "Read" entry.
- StringBuffer readBuffer;
+ StringBuffer? readBuffer;
InstrumentationInputConverter(String tmpSrcDirPath, PathMap srcPathMap)
: super(tmpSrcDirPath, srcPathMap);
@override
- Operation convert(String line) {
+ Operation? convert(String line) {
List<String> fields;
try {
fields = _parseFields(line);
if (fields.length < 2) {
+ var readBuffer = this.readBuffer;
if (readBuffer != null) {
readBuffer.writeln(fields.length == 1 ? fields[0] : '');
return null;
@@ -78,7 +77,7 @@
return null;
}
- Map<String, dynamic> decodeJson(String line, String text) {
+ Map<String, Object?> decodeJson(String line, String text) {
try {
return asMap(json.decode(text));
} catch (e, s) {
diff --git a/pkg/analysis_server/benchmark/integration/local_runner.dart b/pkg/analysis_server/benchmark/integration/local_runner.dart
index e8353b2..f8a987a 100644
--- a/pkg/analysis_server/benchmark/integration/local_runner.dart
+++ b/pkg/analysis_server/benchmark/integration/local_runner.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart = 2.9
-
import 'dart:io';
import 'package:path/path.dart';
@@ -77,7 +75,7 @@
}
/// Print help and exit
-void printHelp([String errMsg]) {
+void printHelp([String? errMsg]) {
if (errMsg != null) {
print('');
print('Error: $errMsg');
diff --git a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
index 238a1fa..bd87c70 100644
--- a/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
+++ b/pkg/analysis_server/benchmark/integration/log_file_input_converter.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart = 2.9
-
import 'dart:convert';
import 'package:analyzer/exception/exception.dart';
@@ -25,7 +23,7 @@
: super(tmpSrcDirPath, srcPathMap);
@override
- Operation convert(String line) {
+ Operation? convert(String line) {
try {
var timeStampString = _parseTimeStamp(line);
var data = line.substring(timeStampString.length);
diff --git a/pkg/analysis_server/benchmark/integration/main.dart b/pkg/analysis_server/benchmark/integration/main.dart
index c1c9911..8f0a438 100644
--- a/pkg/analysis_server/benchmark/integration/main.dart
+++ b/pkg/analysis_server/benchmark/integration/main.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart = 2.9
-
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@@ -26,9 +24,9 @@
var driver = Driver(diagnosticPort: args.diagnosticPort);
var stream = openInput(args);
- StreamSubscription<Operation> subscription;
- subscription = stream.listen((Operation op) {
- var future = driver.perform(op);
+ late StreamSubscription<Operation?> subscription;
+ subscription = stream.listen((Operation? op) {
+ var future = driver.perform(op!);
if (future != null) {
logger.log(Level.FINE, 'pausing operations for ${op.runtimeType}');
subscription.pause(future.then((_) {
@@ -63,17 +61,15 @@
const VERBOSE_CMDLINE_OPTION = 'verbose';
const VERY_VERBOSE_CMDLINE_OPTION = 'vv';
-ArgParser _argParser;
+late final ArgParser argParser = () {
+ var argParser = ArgParser();
-ArgParser get argParser {
- _argParser = ArgParser();
-
- _argParser.addOption(INPUT_CMDLINE_OPTION,
+ argParser.addOption(INPUT_CMDLINE_OPTION,
abbr: 'i',
help: '<filePath>\n'
'The input file specifying how this client should interact with the server.\n'
'If the input file name is "stdin", then the instructions are read from standard input.');
- _argParser.addMultiOption(MAP_OPTION,
+ argParser.addMultiOption(MAP_OPTION,
abbr: 'm',
splitCommas: false,
help: '<oldSrcPath>,<newSrcPath>\n'
@@ -82,26 +78,26 @@
'to the target source directory <newSrcPath> used during performance testing.\n'
'Multiple mappings can be specified.\n'
'WARNING: The contents of the target directory will be modified');
- _argParser.addOption(TMP_SRC_DIR_OPTION,
+ argParser.addOption(TMP_SRC_DIR_OPTION,
abbr: 't',
help: '<dirPath>\n'
'The temporary directory containing source used during performance measurement.\n'
'WARNING: The contents of the target directory will be modified');
- _argParser.addOption(DIAGNOSTIC_PORT_OPTION,
+ argParser.addOption(DIAGNOSTIC_PORT_OPTION,
abbr: 'd',
help: 'localhost port on which server will provide diagnostic web pages');
- _argParser.addFlag(VERBOSE_CMDLINE_OPTION,
+ argParser.addFlag(VERBOSE_CMDLINE_OPTION,
abbr: 'v', help: 'Verbose logging', negatable: false);
- _argParser.addFlag(VERY_VERBOSE_CMDLINE_OPTION,
+ argParser.addFlag(VERY_VERBOSE_CMDLINE_OPTION,
help: 'Extra verbose logging', negatable: false);
- _argParser.addFlag(HELP_CMDLINE_OPTION,
+ argParser.addFlag(HELP_CMDLINE_OPTION,
abbr: 'h', help: 'Print this help information', negatable: false);
- return _argParser;
-}
+ return argParser;
+}();
/// Open and return the input stream specifying how this client
/// should interact with the analysis server.
-Stream<Operation> openInput(PerfArgs args) {
+Stream<Operation?> openInput(PerfArgs args) {
var logger = Logger('openInput');
Stream<List<int>> inputRaw;
if (args.inputPath == 'stdin') {
@@ -137,12 +133,12 @@
var showHelp = args[HELP_CMDLINE_OPTION] || args.rest.isNotEmpty;
- bool isMissing(key) => args[key] == null || args[key].isEmpty;
-
- perfArgs.inputPath = args[INPUT_CMDLINE_OPTION];
- if (isMissing(INPUT_CMDLINE_OPTION)) {
+ var inputArg = args[INPUT_CMDLINE_OPTION];
+ if (inputArg is! String || inputArg.isEmpty) {
print('missing $INPUT_CMDLINE_OPTION argument');
showHelp = true;
+ } else {
+ perfArgs.inputPath = inputArg;
}
for (String pair in args[MAP_OPTION]) {
@@ -157,18 +153,20 @@
}
}
}
- print('must specifiy $MAP_OPTION <oldSrcPath>,<newSrcPath>');
+ print('must specify $MAP_OPTION <oldSrcPath>,<newSrcPath>');
showHelp = true;
}
- perfArgs.tmpSrcDirPath = _withTrailingSeparator(args[TMP_SRC_DIR_OPTION]);
- if (isMissing(TMP_SRC_DIR_OPTION)) {
+ var tmpSrcDirPathArg = args[TMP_SRC_DIR_OPTION];
+ if (tmpSrcDirPathArg is! String || tmpSrcDirPathArg.isEmpty) {
print('missing $TMP_SRC_DIR_OPTION argument');
showHelp = true;
+ } else {
+ perfArgs.tmpSrcDirPath = _withTrailingSeparator(tmpSrcDirPathArg);
}
- String portText = args[DIAGNOSTIC_PORT_OPTION];
- if (portText != null) {
+ var portText = args[DIAGNOSTIC_PORT_OPTION];
+ if (portText is String) {
if (int.tryParse(portText) == null) {
print('invalid $DIAGNOSTIC_PORT_OPTION: $portText');
showHelp = true;
@@ -202,7 +200,7 @@
/// Ensure that the given path has a trailing separator
String _withTrailingSeparator(String dirPath) {
- if (dirPath != null && dirPath.length > 4) {
+ if (dirPath.length > 4) {
if (!dirPath.endsWith(path.separator)) {
return '$dirPath${path.separator}';
}
@@ -215,7 +213,7 @@
/// The file path of the instrumentation or log file
/// used to drive performance measurement,
/// or 'stdin' if this information should be read from standard input.
- String inputPath;
+ late String inputPath;
/// A mapping from the original source directory
/// when the instrumentation or log file was generated
@@ -224,8 +222,8 @@
/// The temporary directory containing source used during performance
/// measurement.
- String tmpSrcDirPath;
+ late String tmpSrcDirPath;
/// The diagnostic port for Analysis Server or `null` if none.
- int diagnosticPort;
+ int? diagnosticPort;
}
diff --git a/pkg/analysis_server/benchmark/integration/operation.dart b/pkg/analysis_server/benchmark/integration/operation.dart
index eb70f44..311e979 100644
--- a/pkg/analysis_server/benchmark/integration/operation.dart
+++ b/pkg/analysis_server/benchmark/integration/operation.dart
@@ -2,8 +2,6 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
-// @dart = 2.9
-
import 'dart:async';
import 'package:analysis_server/protocol/protocol_generated.dart';
@@ -15,10 +13,10 @@
/// A [CompletionRequestOperation] tracks response time along with
/// the first and last completion notifications.
class CompletionRequestOperation extends RequestOperation {
- Driver driver;
- StreamSubscription<CompletionResultsParams> subscription;
- String notificationId;
- Stopwatch stopwatch;
+ late Driver driver;
+ late StreamSubscription<CompletionResultsParams> subscription;
+ late String notificationId;
+ late Stopwatch stopwatch;
bool firstNotification = true;
CompletionRequestOperation(
@@ -26,7 +24,7 @@
: super(converter, json);
@override
- Future perform(Driver driver) {
+ Future<void>? perform(Driver driver) {
this.driver = driver;
subscription = driver.onCompletionResults.listen(processNotification);
return super.perform(driver);
@@ -50,8 +48,8 @@
@override
void processResult(
- String id, Map<String, dynamic> result, Stopwatch stopwatch) {
- notificationId = result['id'];
+ String id, Map<String, Object?> result, Stopwatch stopwatch) {
+ notificationId = result['id'] as String;
this.stopwatch = stopwatch;
super.processResult(id, result, stopwatch);
}
@@ -59,7 +57,7 @@
/// An [Operation] represents an action such as sending a request to the server.
abstract class Operation {
- Future perform(Driver driver);
+ Future<void>? perform(Driver driver);
}
/// A [RequestOperation] sends a [JSON] request to the server.
@@ -70,7 +68,7 @@
RequestOperation(this.converter, this.json);
@override
- Future perform(Driver driver) {
+ Future<void>? perform(Driver driver) {
var stopwatch = Stopwatch();
String originalId = json['id'];
String method = json['method'];
@@ -85,11 +83,9 @@
.log(Level.FINE, 'Response received: $method : $elapsed\n $result');
}
- driver
- .send(method, converter.asMap(json['params']))
- .then((Map<String, dynamic> result) {
+ driver.send(method, converter.asMap(json['params'])).then((result) {
recordResult(true, result);
- processResult(originalId, result, stopwatch);
+ processResult(originalId, result!, stopwatch);
}).catchError((exception) {
recordResult(false, exception);
converter.processErrorResponse(originalId, exception);
@@ -98,7 +94,7 @@
}
void processResult(
- String id, Map<String, dynamic> result, Stopwatch stopwatch) {
+ String id, Map<String, Object?> result, Stopwatch stopwatch) {
converter.processResponseResult(id, result);
}
}
@@ -107,19 +103,20 @@
class ResponseOperation extends Operation {
static final Duration responseTimeout = Duration(seconds: 60);
final CommonInputConverter converter;
- final Map<String, dynamic> requestJson;
- final Map<String, dynamic> responseJson;
+ final Map<String, Object?> requestJson;
+ final Map<String, Object?> responseJson;
final Completer completer = Completer();
- Driver driver;
+ late Driver driver;
ResponseOperation(this.converter, this.requestJson, this.responseJson) {
completer.future.then(_processResult).timeout(responseTimeout);
}
@override
- Future perform(Driver driver) {
+ Future<void>? perform(Driver driver) {
this.driver = driver;
- return converter.processExpectedResponse(responseJson['id'], completer);
+ var id = responseJson['id'] as String;
+ return converter.processExpectedResponse(id, completer);
}
bool _equal(expectedResult, actualResult) {
@@ -161,7 +158,8 @@
'expected result:${format(expectedResult)}\n'
'expected error:${format(expectedError)}\n'
'but received:${format(actualResult)}';
- driver.results.recordUnexpectedResults(requestJson['method']);
+ var method = requestJson['method'] as String;
+ driver.results.recordUnexpectedResults(method);
converter.logOverlayContent();
if (expectedError == null) {
converter.logger.log(Level.SEVERE, message);
@@ -184,13 +182,14 @@
Future perform(Driver driver) {
var start = DateTime.now();
driver.logger.log(Level.FINE, 'waiting for analysis to complete');
- StreamSubscription<ServerStatusParams> subscription;
- Timer timer;
+ late StreamSubscription<ServerStatusParams> subscription;
+ late Timer timer;
var completer = Completer();
var isAnalyzing = false;
subscription = driver.onServerStatus.listen((ServerStatusParams params) {
- if (params.analysis != null) {
- if (params.analysis.isAnalyzing) {
+ var analysisStatus = params.analysis;
+ if (analysisStatus != null) {
+ if (analysisStatus.isAnalyzing) {
isAnalyzing = true;
} else {
subscription.cancel();
@@ -214,7 +213,7 @@
}
// Timeout if no communication received within the last 60 seconds.
var currentTime = driver.server.currentElapseTime;
- var lastTime = driver.server.lastCommunicationTime;
+ var lastTime = driver.server.lastCommunicationTime!;
if (currentTime - lastTime > 60) {
subscription.cancel();
timer.cancel();