Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Unified Diff: pkg/analysis_server/test/performance/input_converter.dart

Issue 1202843010: performance measurement: generate report (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merge Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analysis_server/test/performance/input_converter.dart
diff --git a/pkg/analysis_server/test/performance/input_converter.dart b/pkg/analysis_server/test/performance/input_converter.dart
index 9acf61a71c56560912b7f93a1ee5e902b97032bf..ccf598e9d2a5552f47594c70aeb147027c00e451 100644
--- a/pkg/analysis_server/test/performance/input_converter.dart
+++ b/pkg/analysis_server/test/performance/input_converter.dart
@@ -4,12 +4,12 @@
library input.transformer;
+import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol.dart';
-import 'package:analyzer/src/generated/java_engine.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as path;
@@ -26,16 +26,31 @@ abstract class CommonInputConverter extends Converter<String, Operation> {
final Set<String> eventsSeen = new Set<String>();
/**
- * A mapping from request/response id to expected error message.
+ * A mapping from request/response id to request json
+ * for those requests for which a response has not been processed.
*/
- final Map<String, dynamic> expectedErrors = new Map<String, dynamic>();
+ final Map<String, dynamic> requestMap = {};
+
+ /**
+ * A mapping from request/response id to a completer
+ * for those requests for which a response has not been processed.
+ * The completer is called with the actual json response
+ * when it becomes available.
+ */
+ final Map<String, Completer> responseCompleters = {};
+
+ /**
+ * A mapping from request/response id to the actual response result
+ * for those responses that have not been processed.
+ */
+ final Map<String, dynamic> responseMap = {};
/**
* A mapping of current overlay content
* parallel to what is in the analysis server
* so that we can update the file system.
*/
- final Map<String, String> overlays = new Map<String, String>();
+ final Map<String, String> overlays = {};
/**
* The prefix used to determine if a request parameter is a file path.
@@ -87,54 +102,54 @@ abstract class CommonInputConverter extends Converter<String, Operation> {
*/
Operation convertRequest(Map<String, dynamic> origJson) {
Map<String, dynamic> json = translateSrcPaths(origJson);
+ requestMap[json['id']] = json;
String method = json['method'];
// Sanity check operations that modify source
// to ensure that the operation is on source in temp space
if (method == ANALYSIS_UPDATE_CONTENT) {
- try {
- validateSrcPaths(json);
- } catch (e, s) {
- throw new AnalysisException('invalid src path in update request\n$json',
- new CaughtException(e, s));
- }
// Track overlays in parallel with the analysis server
// so that when an overlay is removed, the file can be updated on disk
Request request = new Request.fromJson(json);
var params = new AnalysisUpdateContentParams.fromRequest(request);
- params.files.forEach((String path, change) {
+ params.files.forEach((String filePath, change) {
if (change is AddContentOverlay) {
String content = change.content;
if (content == null) {
throw 'expected new overlay content\n$json';
}
- overlays[path] = content;
+ overlays[filePath] = content;
} else if (change is ChangeContentOverlay) {
- String content = overlays[path];
+ String content = overlays[filePath];
if (content == null) {
throw 'expected cached overlay content\n$json';
}
- overlays[path] = SourceEdit.applySequence(content, change.edits);
+ overlays[filePath] = SourceEdit.applySequence(content, change.edits);
} else if (change is RemoveContentOverlay) {
- String content = overlays.remove(path);
+ String content = overlays.remove(filePath);
if (content == null) {
throw 'expected cached overlay content\n$json';
}
- validateSrcPaths(path);
- new File(path).writeAsStringSync(content);
+ if (!path.isWithin(tmpSrcDirPath, filePath)) {
+ throw 'found path referencing source outside temp space\n$filePath\n$json';
+ }
+ new File(filePath).writeAsStringSync(content);
} else {
throw 'unknown overlay change $change\n$json';
}
});
return new RequestOperation(this, json);
}
- // TODO(danrubel) replace this with code
+ // Track performance for completion notifications
+ if (method == COMPLETION_GET_SUGGESTIONS) {
+ return new CompletionRequestOperation(this, json);
+ }
+ // TODO(danrubel) replace this with code
// that just forwards the translated request
if (method == ANALYSIS_GET_HOVER ||
method == ANALYSIS_SET_ANALYSIS_ROOTS ||
method == ANALYSIS_SET_PRIORITY_FILES ||
method == ANALYSIS_SET_SUBSCRIPTIONS ||
method == ANALYSIS_UPDATE_OPTIONS ||
- method == COMPLETION_GET_SUGGESTIONS ||
method == EDIT_GET_ASSISTS ||
method == EDIT_GET_AVAILABLE_REFACTORINGS ||
method == EDIT_GET_FIXES ||
@@ -145,6 +160,7 @@ abstract class CommonInputConverter extends Converter<String, Operation> {
method == EXECUTION_MAP_URI ||
method == EXECUTION_SET_SUBSCRIPTIONS ||
method == SEARCH_FIND_ELEMENT_REFERENCES ||
+ method == SEARCH_FIND_MEMBER_DECLARATIONS ||
method == SERVER_GET_VERSION ||
method == SERVER_SET_SUBSCRIPTIONS) {
return new RequestOperation(this, json);
@@ -153,49 +169,63 @@ abstract class CommonInputConverter extends Converter<String, Operation> {
}
/**
- * Determine if the given request is expected to fail
- * and log an exception if not.
+ * Return an operation for the recorded/expected response.
*/
- void recordErrorResponse(Map<String, dynamic> jsonRequest, exception) {
- var actualErr;
+ Operation convertResponse(Map<String, dynamic> json) {
+ return new ResponseOperation(
+ this, requestMap.remove(json['id']), translateSrcPaths(json));
+ }
+
+ /**
+ * Process an error response from the server by either
+ * completing the associated completer in the [responseCompleters]
+ * or stashing it in [responseMap] if no completer exists.
+ */
+ void processErrorResponse(String id, exception) {
+ var result = exception;
if (exception is UnimplementedError) {
if (exception.message.startsWith(ERROR_PREFIX)) {
- Map<String, dynamic> jsonResponse =
- JSON.decode(exception.message.substring(ERROR_PREFIX.length));
- actualErr = jsonResponse['error'];
+ result = JSON.decode(exception.message.substring(ERROR_PREFIX.length));
}
}
- String id = jsonRequest['id'];
- if (id != null && actualErr != null) {
- var expectedErr = expectedErrors[id];
- if (expectedErr != null && actualErr == expectedErr) {
- return;
- }
-// if (jsonRequest['method'] == EDIT_SORT_MEMBERS) {
-// var params = jsonRequest['params'];
-// if (params is Map) {
-// var filePath = params['file'];
-// if (filePath is String) {
-// var content = overlays[filePath];
-// if (content is String) {
-// logger.log(Level.WARNING, 'sort failed: $filePath\n$content');
-// }
-// }
-// }
-// }
+ processResponseResult(id, result);
+ }
+
+ /**
+ * Process the expected response by completing the given completer
+ * with the result if it has alredy been received,
+ * or caching the completer to be completed when the server
+ * returns the associated result.
+ * 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) {
+ if (responseMap.containsKey(id)) {
+ logger.log(Level.INFO, 'processing cached response $id');
+ completer.complete(responseMap.remove(id));
+ return null;
+ } else {
+ logger.log(Level.INFO, 'waiting for response $id');
+ responseCompleters[id] = completer;
+ return completer.future;
}
- logger.log(
- Level.SEVERE, 'Send request failed for $id\n$exception\n$jsonRequest');
}
/**
- * Examine recorded responses and record any expected errors.
+ * Process a success response result from the server by either
+ * completing the associated completer in the [responseCompleters]
+ * or stashing it in [responseMap] if no completer exists.
+ * The response result may be `null`.
*/
- void recordResponse(Map<String, dynamic> json) {
- var error = json['error'];
- if (error != null) {
- String id = json['id'];
- print('expected error for $id is $error');
+ void processResponseResult(String id, result) {
+ Completer completer = responseCompleters[id];
+ if (completer != null) {
+ logger.log(Level.INFO, 'processing response $id');
+ completer.complete(result);
+ } else {
+ logger.log(Level.INFO, 'caching response $id');
+ responseMap[id] = result;
}
}
@@ -230,29 +260,6 @@ abstract class CommonInputConverter extends Converter<String, Operation> {
}
return json;
}
-
- /**
- * Recursively verify that the source paths in the specified JSON
- * only reference the temporary source used during performance measurement.
- */
- void validateSrcPaths(json) {
- if (json is String) {
- if (json != null &&
- path.isWithin(rootPrefix, json) &&
- !path.isWithin(tmpSrcDirPath, json)) {
- throw 'found path referencing source outside temp space\n$json';
- }
- } else if (json is List) {
- for (int i = json.length - 1; i >= 0; --i) {
- validateSrcPaths(json[i]);
- }
- } else if (json is Map) {
- json.forEach((String key, value) {
- validateSrcPaths(key);
- validateSrcPaths(value);
- });
- }
- }
}
/**

Powered by Google App Engine
This is Rietveld 408576698