Chromium Code Reviews| Index: pkg/analysis_server/benchmark/perf/memory_tests.dart |
| diff --git a/pkg/analysis_server/benchmark/perf/memory_tests.dart b/pkg/analysis_server/benchmark/perf/memory_tests.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8522430cb25b3bcd01f671f4600532f97dcf44e0 |
| --- /dev/null |
| +++ b/pkg/analysis_server/benchmark/perf/memory_tests.dart |
| @@ -0,0 +1,125 @@ |
| +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| +// 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. |
| + |
| +import 'dart:async'; |
| +import 'dart:convert'; |
| +import 'dart:io'; |
| + |
| +import 'package:analysis_server/plugin/protocol/protocol.dart'; |
| +import 'package:unittest/unittest.dart'; |
| + |
| +import '../../test/integration/integration_tests.dart'; |
| + |
| +void printMemoryResults(String id, String description, List<int> sizes) { |
| + String now = new DateTime.now().toUtc().toIso8601String(); |
| + print('$now ========== $id'); |
| + print('memory: $sizes'); |
| + print(description.trim()); |
| + print('--------------------'); |
| + print(''); |
| + print(''); |
| +} |
| + |
| +/** |
| + * Base class for analysis server memory usage tests. |
| + */ |
| +class AnalysisServerMemoryUsageTest |
| + extends AbstractAnalysisServerIntegrationTest { |
| + static const int vmServicePort = 12345; |
| + |
| + int getMemoryUsage() { |
| + ProcessResult result = _run('curl', <String>[ |
| + 'localhost:$vmServicePort/_getAllocationProfile\?isolateId=isolates/root\&gc=full' |
| + ]); |
| + Map json = JSON.decode(result.stdout); |
| + Map heaps = json['result']['heaps']; |
| + int newSpace = heaps['new']['used']; |
| + int oldSpace = heaps['old']['used']; |
| + return newSpace + oldSpace; |
| + } |
| + |
| + /** |
| + * Send the server an 'analysis.setAnalysisRoots' command directing it to |
| + * analyze [sourceDirectory]. |
| + */ |
| + Future setAnalysisRoot() => |
| + sendAnalysisSetAnalysisRoots([sourceDirectory.path], []); |
| + |
| + /** |
| + * The server is automatically started before every test. |
| + */ |
| + @override |
| + Future setUp() { |
| + onAnalysisErrors.listen((AnalysisErrorsParams params) { |
| + currentAnalysisErrors[params.file] = params.errors; |
| + }); |
| + onServerError.listen((ServerErrorParams params) { |
| + // A server error should never happen during an integration test. |
| + fail('${params.message}\n${params.stackTrace}'); |
| + }); |
| + Completer serverConnected = new Completer(); |
| + onServerConnected.listen((_) { |
| + expect(serverConnected.isCompleted, isFalse); |
| + serverConnected.complete(); |
| + }); |
| + return startServer(servicesPort: vmServicePort).then((_) { |
| + server.listenToOutput(dispatchNotification); |
| + server.exitCode.then((_) { |
| + skipShutdown = true; |
| + }); |
| + return serverConnected.future; |
| + }); |
| + } |
| + |
| + /** |
| + * After every test, the server is stopped. |
| + */ |
| + Future shutdown() async => await shutdownIfNeeded(); |
| + |
| + /** |
| + * Enable [ServerService.STATUS] notifications so that [analysisFinished] |
| + * can be used. |
| + */ |
| + Future subscribeToStatusNotifications() async { |
| + await sendServerSetSubscriptions([ServerService.STATUS]); |
| + } |
| + |
| + /** |
| + * Synchronously run the given [executable] with the given [arguments]. Return |
| + * the result of running the process. |
| + */ |
| + ProcessResult _run(String executable, List<String> arguments) { |
| + return Process.runSync(executable, arguments, |
| + stderrEncoding: UTF8, stdoutEncoding: UTF8); |
| + } |
| + |
| + /** |
| + * 1. Start Analysis Server. |
| + * 2. Set the analysis [roots]. |
| + * 3. Wait for analysis to complete. |
| + * 4. Record the time to finish analysis. |
|
scheglov
2016/07/06 17:55:04
Record the heap size after analysis is finished?
|
| + * 5. Shutdown. |
| + * 6. Go to (1). |
| + */ |
| + static Future<List<int>> start_waitInitialAnalysis_shutdown( |
| + {List<String> roots, int numOfRepeats}) async { |
| + expect(roots, isNotNull, reason: 'roots'); |
| + expect(numOfRepeats, isNotNull, reason: 'numOfRepeats'); |
| + // Repeat. |
| + List<int> sizes = <int>[]; |
| + for (int i = 0; i < numOfRepeats; i++) { |
| + AnalysisServerMemoryUsageTest test = new AnalysisServerMemoryUsageTest(); |
| + // Initialize Analysis Server. |
| + await test.setUp(); |
| + await test.subscribeToStatusNotifications(); |
| + // Set roots and analyze. |
| + await test.sendAnalysisSetAnalysisRoots(roots, []); |
| + await test.analysisFinished; |
| + sizes.add(test.getMemoryUsage()); |
| + // Stop the server. |
| + await test.shutdown(); |
| + } |
| + return sizes; |
| + } |
| +} |