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

Side by Side Diff: pkg/analysis_server/test/integration/integration_tests.dart

Issue 426243005: Make "server.shutdown" exit the analysis server. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 4 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 test.integration.analysis; 5 library test.integration.analysis;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:convert'; 9 import 'dart:convert';
10 import 'dart:io'; 10 import 'dart:io';
11 11
12 import 'package:analysis_server/src/constants.dart'; 12 import 'package:analysis_server/src/constants.dart';
13 import 'package:path/path.dart'; 13 import 'package:path/path.dart';
14 import 'package:unittest/unittest.dart'; 14 import 'package:unittest/unittest.dart';
15 15
16 /** 16 /**
17 * Base class for analysis server integration tests. 17 * Base class for analysis server integration tests.
18 */ 18 */
19 abstract class AbstractAnalysisServerIntegrationTest { 19 abstract class AbstractAnalysisServerIntegrationTest {
20 /** 20 /**
21 * Amount of time to give the server to respond to a shutdown request before
22 * forcibly terminating it.
23 */
24 static const Duration SHUTDOWN_TIMEOUT = const Duration(seconds: 5);
25
26 /**
21 * Connection to the analysis server. 27 * Connection to the analysis server.
22 */ 28 */
23 Server server; 29 Server server;
24 30
25 /** 31 /**
26 * Temporary directory in which source files can be stored. 32 * Temporary directory in which source files can be stored.
27 */ 33 */
28 Directory sourceDirectory; 34 Directory sourceDirectory;
29 35
30 /** 36 /**
31 * Map from file path to the list of analysis errors which have most recently 37 * Map from file path to the list of analysis errors which have most recently
32 * been received for the file. 38 * been received for the file.
33 */ 39 */
34 HashMap<String, dynamic> currentAnalysisErrors = new HashMap<String, dynamic>( 40 HashMap<String, dynamic> currentAnalysisErrors = new HashMap<String, dynamic>(
35 ); 41 );
36 42
37 /** 43 /**
44 * True if the teardown process should skip sending a "server.shutdown"
45 * request (e.g. because the server is known to have already shutdown).
46 */
47 bool skipShutdown = false;
48
49 /**
38 * Write a source file with the given contents. [relativePath] 50 * Write a source file with the given contents. [relativePath]
39 * is relative to [sourceDirectory]; on Windows any forward slashes it 51 * is relative to [sourceDirectory]; on Windows any forward slashes it
40 * contains are converted to backslashes. 52 * contains are converted to backslashes.
41 * 53 *
42 * If the file didn't previously exist, it is created. If it did, it is 54 * If the file didn't previously exist, it is created. If it did, it is
43 * overwritten. 55 * overwritten.
44 */ 56 */
45 void writeFile(String relativePath, String contents) { 57 void writeFile(String relativePath, String contents) {
46 String absolutePath = normalizePath(relativePath); 58 String absolutePath = normalizePath(relativePath);
47 new Directory(dirname(absolutePath)).createSync(recursive: true); 59 new Directory(dirname(absolutePath)).createSync(recursive: true);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 */ 131 */
120 Future setUp() { 132 Future setUp() {
121 sourceDirectory = Directory.systemTemp.createTempSync('analysisServer'); 133 sourceDirectory = Directory.systemTemp.createTempSync('analysisServer');
122 return Server.start().then((Server server) { 134 return Server.start().then((Server server) {
123 this.server = server; 135 this.server = server;
124 server.onNotification(ANALYSIS_ERRORS).listen((params) { 136 server.onNotification(ANALYSIS_ERRORS).listen((params) {
125 expect(params, isMap); 137 expect(params, isMap);
126 expect(params['file'], isString); 138 expect(params['file'], isString);
127 currentAnalysisErrors[params['file']] = params['errors']; 139 currentAnalysisErrors[params['file']] = params['errors'];
128 }); 140 });
141 server.exitCode.then((_) { skipShutdown = true; });
129 }); 142 });
130 } 143 }
131 144
132 /** 145 /**
133 * After every test, the server stopped and [sourceDirectory] is deleted. 146 * After every test, the server is stopped and [sourceDirectory] is deleted.
134 */ 147 */
135 Future tearDown() { 148 Future tearDown() {
136 return server.kill().then((_) { 149 return _shutdownIfNeeded().then((_) {
137 sourceDirectory.deleteSync(recursive: true); 150 sourceDirectory.deleteSync(recursive: true);
138 }); 151 });
139 } 152 }
153
154 /**
155 * If [skipShutdown] is not set, shut down the server.
156 */
157 Future _shutdownIfNeeded() {
158 if (skipShutdown) {
159 return new Future.value();
160 }
161 // Give the server a short time to comply with the shutdown request; if it
162 // doesn't exit, then forcibly terminate it.
163 Completer processExited = new Completer();
164 server.send(SERVER_SHUTDOWN, null);
165 server.exitCode.whenComplete(() {
166 processExited.complete();
167 });
168 new Future.delayed(SHUTDOWN_TIMEOUT).then((_) {
169 if (!processExited.isCompleted) {
170 server.kill();
171 }
172 });
173 return processExited.future;
174 }
140 } 175 }
141 176
142 // Matchers for data types defined in the analysis server API 177 // Matchers for data types defined in the analysis server API
143 // ========================================================== 178 // ==========================================================
144 // TODO(paulberry): add more matchers. 179 // TODO(paulberry): add more matchers.
145 180
146 // Matchers common to all domains 181 // Matchers common to all domains
147 // ------------------------------ 182 // ------------------------------
148 183
149 const Matcher isResponse = const MatchesJsonObject('response', const { 184 const Matcher isResponse = const MatchesJsonObject('response', const {
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 // event of an error. 606 // event of an error.
572 expect(message, isNotification); 607 expect(message, isNotification);
573 } 608 }
574 }); 609 });
575 process.stderr.transform((new Utf8Codec()).decoder).transform( 610 process.stderr.transform((new Utf8Codec()).decoder).transform(
576 new LineSplitter()).listen((String line) { 611 new LineSplitter()).listen((String line) {
577 String trimmedLine = line.trim(); 612 String trimmedLine = line.trim();
578 server._recordStdio('ERR: $trimmedLine'); 613 server._recordStdio('ERR: $trimmedLine');
579 server._badDataFromServer(); 614 server._badDataFromServer();
580 }); 615 });
616 process.exitCode.then((int code) {
617 server._recordStdio('TERMINATED WITH EXIT CODE $code');
618 if (code != 0) {
619 server._badDataFromServer();
620 }
621 });
581 return server; 622 return server;
582 }); 623 });
583 } 624 }
584 625
585 /** 626 /**
627 * Future that completes when the server process exits.
628 */
629 Future<int> get exitCode => _process.exitCode;
630
631 /**
586 * Stop the server. 632 * Stop the server.
587 */ 633 */
588 Future kill() { 634 Future kill() {
635 debugStdio();
636 _recordStdio('PROCESS FORCIBLY TERMINATED');
589 _process.kill(); 637 _process.kill();
590 return _process.exitCode; 638 return _process.exitCode;
591 } 639 }
592 640
593 /** 641 /**
594 * Send a command to the server. An 'id' will be automatically assigned. 642 * Send a command to the server. An 'id' will be automatically assigned.
595 * The returned [Future] will be completed when the server acknowledges the 643 * The returned [Future] will be completed when the server acknowledges the
596 * command with a response. If the server acknowledges the command with a 644 * command with a response. If the server acknowledges the command with a
597 * normal (non-error) response, the future will be completed with the 'result' 645 * normal (non-error) response, the future will be completed with the 'result'
598 * field from the response. If the server acknowledges the command with an 646 * field from the response. If the server acknowledges the command with an
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 * Record a message that was exchanged with the server, and print it out if 701 * Record a message that was exchanged with the server, and print it out if
654 * [debugStdio] has been called. 702 * [debugStdio] has been called.
655 */ 703 */
656 void _recordStdio(String line) { 704 void _recordStdio(String line) {
657 if (_debuggingStdio) { 705 if (_debuggingStdio) {
658 print(line); 706 print(line);
659 } 707 }
660 _recordedStdio.add(line); 708 _recordedStdio.add(line);
661 } 709 }
662 } 710 }
OLDNEW
« no previous file with comments | « pkg/analysis_server/lib/src/channel.dart ('k') | pkg/analysis_server/test/integration/server_domain_int_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698