| // Copyright (c) 2014, 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:io'; | |
| import 'dart:typed_data'; | |
| import 'package:analysis_server/protocol/protocol.dart'; | |
| import 'package:analysis_server/protocol/protocol_constants.dart'; | |
| import 'package:analysis_server/protocol/protocol_generated.dart'; | |
| import 'package:analysis_server/src/analytics/analytics_manager.dart'; | |
| import 'package:analysis_server/src/legacy_analysis_server.dart'; | |
| import 'package:analysis_server/src/server/crash_reporting_attachments.dart'; | |
| import 'package:analysis_server/src/server/error_notifier.dart'; | |
| import 'package:analysis_server/src/session_logger/session_logger.dart'; | |
| import 'package:analysis_server/src/socket_server.dart'; | |
| import 'package:analysis_server/src/utilities/mocks.dart'; | |
| import 'package:analyzer/src/file_system/timing_resource_provider.dart'; | |
| import 'package:analyzer/src/generated/engine.dart'; | |
| import 'package:analyzer/src/generated/sdk.dart'; | |
| import 'package:test/test.dart'; | |
| import 'package:unified_analytics/unified_analytics.dart'; | |
| void main() { | |
| group('SocketServer', () { | |
| test( | |
| 'createAnalysisServer_successful', | |
| SocketServerTest.createAnalysisServer_successful, | |
| ); | |
| test( | |
| 'createAnalysisServer_alreadyStarted', | |
| SocketServerTest.createAnalysisServer_alreadyStarted, | |
| ); | |
| test( | |
| 'createAnalysisServer_preservesFileByteStore', | |
| SocketServerTest.createAnalysisServer_preservesFileByteStore, | |
| ); | |
| }); | |
| } | |
| class SocketServerTest { | |
| static void createAnalysisServer_alreadyStarted() { | |
| var channel1 = MockServerChannel(); | |
| var channel2 = MockServerChannel(); | |
| var server = _createSocketServer(channel1); | |
| expect( | |
| channel1.notificationsReceived[0].event, | |
| serverNotificationConnected, | |
| ); | |
| server.createAnalysisServer(channel2); | |
| channel1.expectMsgCount(notificationCount: 1); | |
| channel2.expectMsgCount(responseCount: 1); | |
| expect(channel2.responsesReceived[0].id, equals('')); | |
| expect(channel2.responsesReceived[0].error, isNotNull); | |
| expect( | |
| channel2.responsesReceived[0].error!.code, | |
| equals(RequestErrorCode.SERVER_ALREADY_STARTED), | |
| ); | |
| channel2 | |
| .simulateRequestFromClient( | |
| ServerShutdownParams().toRequest('0', clientUriConverter: null), | |
| ) | |
| .then((Response response) { | |
| expect(response.id, equals('0')); | |
| var error = response.error!; | |
| expect(error.code, equals(RequestErrorCode.SERVER_ALREADY_STARTED)); | |
| channel2.expectMsgCount(responseCount: 2); | |
| }); | |
| } | |
| static Future<void> createAnalysisServer_preservesFileByteStore() async { | |
| var cacheFolder = Directory.systemTemp.createTempSync('server-io-timing'); | |
| var channel = MockServerChannel(); | |
| var socketServer = _createSocketServer( | |
| channel, | |
| options: AnalysisServerOptions()..cacheFolder = cacheFolder.path, | |
| ); | |
| try { | |
| var server = socketServer.analysisServer!; | |
| var stats = server.byteStoreStats!; | |
| expect(stats.usesFileByteStore, isTrue); | |
| expect(stats.fileStorePath, contains(cacheFolder.path)); | |
| expect( | |
| server | |
| .timingResourceProvider | |
| .timings[ResourceProviderOperation.resourceGetStateLocation] | |
| ?.count, | |
| greaterThanOrEqualTo(1), | |
| ); | |
| server.byteStore.putGet('io_timing_test', Uint8List.fromList([1, 2, 3])); | |
| expect(server.byteStore.get('io_timing_test'), [1, 2, 3]); | |
| } finally { | |
| await channel.simulateRequestFromClient( | |
| ServerShutdownParams().toRequest('0', clientUriConverter: null), | |
| ); | |
| cacheFolder.deleteSync(recursive: true); | |
| } | |
| } | |
| static Future<void> createAnalysisServer_successful() { | |
| var channel = MockServerChannel(); | |
| _createSocketServer(channel); | |
| channel.expectMsgCount(notificationCount: 1); | |
| expect(channel.notificationsReceived[0].event, serverNotificationConnected); | |
| return channel | |
| .simulateRequestFromClient( | |
| ServerShutdownParams().toRequest('0', clientUriConverter: null), | |
| ) | |
| .then((Response response) { | |
| expect(response.id, equals('0')); | |
| expect(response.error, isNull); | |
| channel.expectMsgCount(responseCount: 1, notificationCount: 1); | |
| }); | |
| } | |
| static SocketServer _createSocketServer( | |
| MockServerChannel channel, { | |
| AnalysisServerOptions? options, | |
| }) { | |
| var errorNotifier = ErrorNotifier(); | |
| var server = SocketServer( | |
| options ?? AnalysisServerOptions(), | |
| DartSdkManager(''), | |
| CrashReportingAttachmentsBuilder.empty, | |
| errorNotifier, | |
| SessionLogger(), | |
| null, | |
| null, | |
| AnalyticsManager(NoOpAnalytics()), | |
| null, | |
| null, | |
| ); | |
| server.createAnalysisServer(channel); | |
| errorNotifier.server = server.analysisServer; | |
| AnalysisEngine.instance.instrumentationService = errorNotifier; | |
| return server; | |
| } | |
| } | |
| extension on MockServerChannel { | |
| void expectMsgCount({int responseCount = 0, int notificationCount = 0}) { | |
| expect(responsesReceived, hasLength(responseCount)); | |
| expect(notificationsReceived, hasLength(notificationCount)); | |
| } | |
| } |