| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library server.driver; | 5 library server.driver; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:math' show max, sqrt; | 8 import 'dart:math' show max, sqrt; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/engine.dart' as engine; | |
| 11 import 'package:logging/logging.dart'; | 10 import 'package:logging/logging.dart'; |
| 12 | 11 |
| 13 import '../../test/integration/integration_test_methods.dart'; | 12 import '../../test/integration/integration_test_methods.dart'; |
| 14 import '../../test/integration/integration_tests.dart'; | 13 import '../../test/integration/integration_tests.dart'; |
| 15 import 'operation.dart'; | 14 import 'operation.dart'; |
| 16 | 15 |
| 17 final SPACE = ' '.codeUnitAt(0); | 16 final SPACE = ' '.codeUnitAt(0); |
| 18 | 17 |
| 19 void _printColumn(StringBuffer sb, String text, int keyLen, | 18 void _printColumn(StringBuffer sb, String text, int keyLen, |
| 20 {bool rightJustified: false}) { | 19 {bool rightJustified: false}) { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 37 * reads a stream of operations, sends requests to analysis server | 36 * reads a stream of operations, sends requests to analysis server |
| 38 * based upon those operations, and evaluates the results. | 37 * based upon those operations, and evaluates the results. |
| 39 */ | 38 */ |
| 40 class Driver extends IntegrationTestMixin { | 39 class Driver extends IntegrationTestMixin { |
| 41 /** | 40 /** |
| 42 * The amount of time to give the server to respond to a shutdown request | 41 * The amount of time to give the server to respond to a shutdown request |
| 43 * before forcibly terminating it. | 42 * before forcibly terminating it. |
| 44 */ | 43 */ |
| 45 static const Duration SHUTDOWN_TIMEOUT = const Duration(seconds: 5); | 44 static const Duration SHUTDOWN_TIMEOUT = const Duration(seconds: 5); |
| 46 | 45 |
| 47 final Logger logger; | 46 final Logger logger = new Logger('Driver'); |
| 47 |
| 48 final bool newTaskModel; |
| 49 |
| 50 /** |
| 51 * The diagnostic port for Analysis Server or `null` if none. |
| 52 */ |
| 53 final int diagnosticPort; |
| 48 | 54 |
| 49 /** | 55 /** |
| 50 * A flag indicating whether the server is running. | 56 * A flag indicating whether the server is running. |
| 51 */ | 57 */ |
| 52 bool running = false; | 58 bool running = false; |
| 53 | 59 |
| 54 @override | 60 @override |
| 55 Server server; | 61 Server server; |
| 56 | 62 |
| 57 /** | 63 /** |
| 58 * The results collected while running analysis server. | 64 * The results collected while running analysis server. |
| 59 */ | 65 */ |
| 60 final Results results = new Results(); | 66 final Results results = new Results(); |
| 61 | 67 |
| 62 /** | 68 /** |
| 63 * The [Completer] for [runComplete]. | 69 * The [Completer] for [runComplete]. |
| 64 */ | 70 */ |
| 65 Completer<Results> _runCompleter = new Completer<Results>(); | 71 Completer<Results> _runCompleter = new Completer<Results>(); |
| 66 | 72 |
| 67 Driver(this.logger); | 73 Driver({this.newTaskModel, this.diagnosticPort}); |
| 68 | 74 |
| 69 /** | 75 /** |
| 70 * Return a [Future] that completes with the [Results] of running | 76 * Return a [Future] that completes with the [Results] of running |
| 71 * the analysis server once all operations have been performed. | 77 * the analysis server once all operations have been performed. |
| 72 */ | 78 */ |
| 73 Future<Results> get runComplete => _runCompleter.future; | 79 Future<Results> get runComplete => _runCompleter.future; |
| 74 | 80 |
| 75 /** | 81 /** |
| 76 * Perform the given operation. | 82 * Perform the given operation. |
| 77 * Return a [Future] that completes when the next operation can be performed, | 83 * Return a [Future] that completes when the next operation can be performed, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 90 * error response, the future will be completed with an error. | 96 * error response, the future will be completed with an error. |
| 91 */ | 97 */ |
| 92 Future send(String method, Map<String, dynamic> params) { | 98 Future send(String method, Map<String, dynamic> params) { |
| 93 return server.send(method, params); | 99 return server.send(method, params); |
| 94 } | 100 } |
| 95 | 101 |
| 96 /** | 102 /** |
| 97 * Launch the analysis server. | 103 * Launch the analysis server. |
| 98 * Return a [Future] that completes when analysis server has started. | 104 * Return a [Future] that completes when analysis server has started. |
| 99 */ | 105 */ |
| 100 Future startServer({int diagnosticPort}) async { | 106 Future startServer() async { |
| 101 logger.log(Level.FINE, 'starting server'); | 107 logger.log(Level.FINE, 'starting server'); |
| 102 initializeInttestMixin(); | 108 initializeInttestMixin(); |
| 103 server = new Server(); | 109 server = new Server(); |
| 104 Completer serverConnected = new Completer(); | 110 Completer serverConnected = new Completer(); |
| 105 onServerConnected.listen((_) { | 111 onServerConnected.listen((_) { |
| 106 logger.log(Level.FINE, 'connected to server'); | 112 logger.log(Level.FINE, 'connected to server'); |
| 107 serverConnected.complete(); | 113 serverConnected.complete(); |
| 108 }); | 114 }); |
| 109 running = true; | 115 running = true; |
| 110 return server | 116 return server |
| 111 .start(diagnosticPort: diagnosticPort /*profileServer: true*/) | 117 .start( |
| 118 diagnosticPort: diagnosticPort, |
| 119 newTaskModel: newTaskModel /*profileServer: true*/) |
| 112 .then((params) { | 120 .then((params) { |
| 113 server.listenToOutput(dispatchNotification); | 121 server.listenToOutput(dispatchNotification); |
| 114 server.exitCode.then((_) { | 122 server.exitCode.then((_) { |
| 115 logger.log(Level.FINE, 'server stopped'); | 123 logger.log(Level.FINE, 'server stopped'); |
| 116 running = false; | 124 running = false; |
| 117 _resultsReady(); | 125 _resultsReady(); |
| 118 }); | 126 }); |
| 119 return serverConnected.future; | 127 return serverConnected.future; |
| 120 }); | 128 }); |
| 121 } | 129 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 int standardDeviation = sqrt(variance).round(); | 194 int standardDeviation = sqrt(variance).round(); |
| 187 | 195 |
| 188 StringBuffer sb = new StringBuffer(); | 196 StringBuffer sb = new StringBuffer(); |
| 189 _printColumn(sb, tag, keyLen); | 197 _printColumn(sb, tag, keyLen); |
| 190 _printColumn(sb, count.toString(), 6, rightJustified: true); | 198 _printColumn(sb, count.toString(), 6, rightJustified: true); |
| 191 _printColumn(sb, errorCount.toString(), 6, rightJustified: true); | 199 _printColumn(sb, errorCount.toString(), 6, rightJustified: true); |
| 192 _printColumn(sb, unexpectedResultCount.toString(), 6, rightJustified: true); | 200 _printColumn(sb, unexpectedResultCount.toString(), 6, rightJustified: true); |
| 193 _printDuration(sb, new Duration(microseconds: meanTime)); | 201 _printDuration(sb, new Duration(microseconds: meanTime)); |
| 194 _printDuration(sb, time90th); | 202 _printDuration(sb, time90th); |
| 195 _printDuration(sb, time99th); | 203 _printDuration(sb, time99th); |
| 196 _printColumn(sb, standardDeviation.toString(), 15, rightJustified: true); | 204 _printDuration(sb, new Duration(microseconds: standardDeviation)); |
| 197 _printDuration(sb, minTime); | 205 _printDuration(sb, minTime); |
| 198 _printDuration(sb, maxTime); | 206 _printDuration(sb, maxTime); |
| 199 _printDuration(sb, new Duration(microseconds: totalTimeMicros)); | 207 _printDuration(sb, new Duration(microseconds: totalTimeMicros)); |
| 200 print(sb.toString()); | 208 print(sb.toString()); |
| 201 } | 209 } |
| 202 | 210 |
| 203 void record(bool success, Duration elapsed) { | 211 void record(bool success, Duration elapsed) { |
| 204 if (!success) { | 212 if (!success) { |
| 205 ++errorCount; | 213 ++errorCount; |
| 206 } | 214 } |
| 207 elapsedTimes.add(elapsed); | 215 elapsedTimes.add(elapsed); |
| 208 } | 216 } |
| 209 | 217 |
| 210 void recordUnexpectedResults() { | 218 void recordUnexpectedResults() { |
| 211 ++unexpectedResultCount; | 219 ++unexpectedResultCount; |
| 212 } | 220 } |
| 213 | 221 |
| 214 void _printDuration(StringBuffer sb, Duration duration) { | 222 void _printDuration(StringBuffer sb, Duration duration) { |
| 215 sb.write(' '); | 223 _printColumn(sb, duration.inMilliseconds.toString(), 15, |
| 216 sb.write(duration); | 224 rightJustified: true); |
| 217 sb.write(','); | |
| 218 } | 225 } |
| 219 } | 226 } |
| 220 | 227 |
| 221 /** | 228 /** |
| 222 * [Results] contains information gathered by [Driver] | 229 * [Results] contains information gathered by [Driver] |
| 223 * while running the analysis server | 230 * while running the analysis server |
| 224 */ | 231 */ |
| 225 class Results { | 232 class Results { |
| 226 Map<String, Measurement> measurements = new Map<String, Measurement>(); | 233 Map<String, Measurement> measurements = new Map<String, Measurement>(); |
| 227 | 234 |
| 228 /** | 235 /** |
| 229 * Display results on stdout. | 236 * Display results on stdout. |
| 230 */ | 237 */ |
| 231 void printResults() { | 238 void printResults() { |
| 232 print(''); | 239 print(''); |
| 233 print('=================================================================='); | 240 print('=================================================================='); |
| 234 if (engine.AnalysisEngine.instance.useTaskModel) { | |
| 235 print('New task model'); | |
| 236 } else { | |
| 237 print('Old task model'); | |
| 238 } | |
| 239 print(''); | 241 print(''); |
| 240 List<String> keys = measurements.keys.toList()..sort(); | 242 List<String> keys = measurements.keys.toList()..sort(); |
| 241 int keyLen = keys.fold(0, (int len, String key) => max(len, key.length)); | 243 int keyLen = keys.fold(0, (int len, String key) => max(len, key.length)); |
| 242 _printGroupHeader('Request/Response', keyLen); | 244 _printGroupHeader('Request/Response', keyLen); |
| 243 int totalCount = 0; | 245 int totalCount = 0; |
| 244 int totalErrorCount = 0; | 246 int totalErrorCount = 0; |
| 245 int totalUnexpectedResultCount = 0; | 247 int totalUnexpectedResultCount = 0; |
| 246 for (String tag in keys) { | 248 for (String tag in keys) { |
| 247 Measurement m = measurements[tag]; | 249 Measurement m = measurements[tag]; |
| 248 if (!m.notification) { | 250 if (!m.notification) { |
| 249 m.printSummary(keyLen); | 251 m.printSummary(keyLen); |
| 250 totalCount += m.count; | 252 totalCount += m.count; |
| 251 totalErrorCount += m.errorCount; | 253 totalErrorCount += m.errorCount; |
| 252 totalUnexpectedResultCount += m.unexpectedResultCount; | 254 totalUnexpectedResultCount += m.unexpectedResultCount; |
| 253 } | 255 } |
| 254 } | 256 } |
| 255 _printTotals( | 257 _printTotals( |
| 256 keyLen, totalCount, totalErrorCount, totalUnexpectedResultCount); | 258 keyLen, totalCount, totalErrorCount, totalUnexpectedResultCount); |
| 257 print(''); | 259 print(''); |
| 258 _printGroupHeader('Notifications', keyLen); | 260 _printGroupHeader('Notifications', keyLen); |
| 259 for (String tag in keys) { | 261 for (String tag in keys) { |
| 260 Measurement m = measurements[tag]; | 262 Measurement m = measurements[tag]; |
| 261 if (m.notification) { | 263 if (m.notification) { |
| 262 m.printSummary(keyLen); | 264 m.printSummary(keyLen); |
| 263 } | 265 } |
| 264 } | 266 } |
| 265 /// TODO(danrubel) *** print warnings if driver caches are not empty **** | 267 /// TODO(danrubel) *** print warnings if driver caches are not empty **** |
| 266 print(''); | 268 print(''' |
| 267 print( | 269 |
| 268 '(1) uxr = UneXpected Results, or responses received from the server'); | 270 (1) uxr = UneXpected Results or responses received from the server |
| 269 print( | 271 that do not match the recorded response for that request. |
| 270 ' that do not match the recorded response for that request.'); | 272 (2) all times in milliseconds'''); |
| 271 } | 273 } |
| 272 | 274 |
| 273 /** | 275 /** |
| 274 * Record the elapsed time for the given operation. | 276 * Record the elapsed time for the given operation. |
| 275 */ | 277 */ |
| 276 void record(String tag, Duration elapsed, | 278 void record(String tag, Duration elapsed, |
| 277 {bool notification: false, bool success: true}) { | 279 {bool notification: false, bool success: true}) { |
| 278 Measurement measurement = measurements[tag]; | 280 Measurement measurement = measurements[tag]; |
| 279 if (measurement == null) { | 281 if (measurement == null) { |
| 280 measurement = new Measurement(tag, notification); | 282 measurement = new Measurement(tag, notification); |
| 281 measurements[tag] = measurement; | 283 measurements[tag] = measurement; |
| 282 } | 284 } |
| 283 measurement.record(success, elapsed); | 285 measurement.record(success, elapsed); |
| 284 } | 286 } |
| 285 | 287 |
| 286 void recordUnexpectedResults(String tag) { | 288 void recordUnexpectedResults(String tag) { |
| 287 measurements[tag].recordUnexpectedResults(); | 289 measurements[tag].recordUnexpectedResults(); |
| 288 } | 290 } |
| 289 | 291 |
| 290 void _printGroupHeader(String groupName, int keyLen) { | 292 void _printGroupHeader(String groupName, int keyLen) { |
| 291 StringBuffer sb = new StringBuffer(); | 293 StringBuffer sb = new StringBuffer(); |
| 292 _printColumn(sb, groupName, keyLen); | 294 _printColumn(sb, groupName, keyLen); |
| 293 _printColumn(sb, 'count', 6, rightJustified: true); | 295 _printColumn(sb, 'count', 6, rightJustified: true); |
| 294 _printColumn(sb, 'error', 6, rightJustified: true); | 296 _printColumn(sb, 'error', 6, rightJustified: true); |
| 295 _printColumn(sb, 'uxr(1)', 6, rightJustified: true); | 297 _printColumn(sb, 'uxr(1)', 6, rightJustified: true); |
| 296 sb.write(' '); | 298 sb.write(' '); |
| 297 _printColumn(sb, 'mean', 15); | 299 _printColumn(sb, 'mean(2)', 15); |
| 298 _printColumn(sb, '90th', 15); | 300 _printColumn(sb, '90th', 15); |
| 299 _printColumn(sb, '99th', 15); | 301 _printColumn(sb, '99th', 15); |
| 300 _printColumn(sb, 'std-dev', 15); | 302 _printColumn(sb, 'std-dev', 15); |
| 301 _printColumn(sb, 'minimum', 15); | 303 _printColumn(sb, 'minimum', 15); |
| 302 _printColumn(sb, 'maximum', 15); | 304 _printColumn(sb, 'maximum', 15); |
| 303 _printColumn(sb, 'total', 15); | 305 _printColumn(sb, 'total', 15); |
| 304 print(sb.toString()); | 306 print(sb.toString()); |
| 305 } | 307 } |
| 306 | 308 |
| 307 void _printTotals(int keyLen, int totalCount, int totalErrorCount, | 309 void _printTotals(int keyLen, int totalCount, int totalErrorCount, |
| 308 int totalUnexpectedResultCount) { | 310 int totalUnexpectedResultCount) { |
| 309 StringBuffer sb = new StringBuffer(); | 311 StringBuffer sb = new StringBuffer(); |
| 310 _printColumn(sb, 'Totals', keyLen); | 312 _printColumn(sb, 'Totals', keyLen); |
| 311 _printColumn(sb, totalCount.toString(), 6, rightJustified: true); | 313 _printColumn(sb, totalCount.toString(), 6, rightJustified: true); |
| 312 _printColumn(sb, totalErrorCount.toString(), 6, rightJustified: true); | 314 _printColumn(sb, totalErrorCount.toString(), 6, rightJustified: true); |
| 313 _printColumn(sb, totalUnexpectedResultCount.toString(), 6, | 315 _printColumn(sb, totalUnexpectedResultCount.toString(), 6, |
| 314 rightJustified: true); | 316 rightJustified: true); |
| 315 print(sb.toString()); | 317 print(sb.toString()); |
| 316 } | 318 } |
| 317 } | 319 } |
| OLD | NEW |