public void OnMessageReceived(object sender, MessageReceivedEventArgs messageReceivedArgs)
        {
            var message = this.dataSerializer.DeserializeMessage(messageReceivedArgs.Data);

            if (EqtTrace.IsInfoEnabled)
            {
                EqtTrace.Info("TestRequestHandler.ProcessRequests: received message: {0}", message);
            }

            switch (message.MessageType)
            {
            case MessageType.VersionCheck:
                var version = this.dataSerializer.DeserializePayload <int>(message);
                this.protocolVersion = Math.Min(version, highestSupportedVersion);

                // Send the negotiated protocol to request sender
                this.channel.Send(this.dataSerializer.SerializePayload(MessageType.VersionCheck, this.protocolVersion));

                // Can only do this after InitializeCommunication because TestHost cannot "Send Log" unless communications are initialized
                if (!string.IsNullOrEmpty(EqtTrace.LogFile))
                {
                    this.SendLog(TestMessageLevel.Informational, string.Format(CrossPlatResources.TesthostDiagLogOutputFile, EqtTrace.LogFile));
                }
                else if (!string.IsNullOrEmpty(EqtTrace.ErrorOnInitialization))
                {
                    this.SendLog(TestMessageLevel.Warning, EqtTrace.ErrorOnInitialization);
                }
                break;

            case MessageType.DiscoveryInitialize:
            {
                EqtTrace.Info("Discovery Session Initialize.");
                this.testHostManagerFactoryReady.Wait();
                var discoveryEventsHandler     = new TestDiscoveryEventHandler(this);
                var pathToAdditionalExtensions = this.dataSerializer.DeserializePayload <IEnumerable <string> >(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetDiscoveryManager().Initialize(pathToAdditionalExtensions, discoveryEventsHandler), 0);
                break;
            }

            case MessageType.StartDiscovery:
            {
                EqtTrace.Info("Discovery started.");
                this.testHostManagerFactoryReady.Wait();
                var discoveryEventsHandler = new TestDiscoveryEventHandler(this);
                var discoveryCriteria      = this.dataSerializer.DeserializePayload <DiscoveryCriteria>(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetDiscoveryManager()
                    .DiscoverTests(discoveryCriteria, discoveryEventsHandler), 0);

                break;
            }

            case MessageType.ExecutionInitialize:
            {
                EqtTrace.Info("Execution Session Initialize.");
                this.testHostManagerFactoryReady.Wait();
                var testInitializeEventsHandler = new TestInitializeEventsHandler(this);
                var pathToAdditionalExtensions  = this.dataSerializer.DeserializePayload <IEnumerable <string> >(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager().Initialize(pathToAdditionalExtensions, testInitializeEventsHandler), 0);
                break;
            }

            case MessageType.StartTestExecutionWithSources:
            {
                EqtTrace.Info("Execution started.");
                var testRunEventsHandler = new TestRunEventsHandler(this);
                this.testHostManagerFactoryReady.Wait();
                var testRunCriteriaWithSources = this.dataSerializer.DeserializePayload <TestRunCriteriaWithSources>(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager()
                    .StartTestRun(
                        testRunCriteriaWithSources.AdapterSourceMap,
                        testRunCriteriaWithSources.Package,
                        testRunCriteriaWithSources.RunSettings,
                        testRunCriteriaWithSources.TestExecutionContext,
                        this.GetTestCaseEventsHandler(testRunCriteriaWithSources.RunSettings),
                        testRunEventsHandler),
                    0);

                break;
            }

            case MessageType.StartTestExecutionWithTests:
            {
                EqtTrace.Info("Execution started.");
                var testRunEventsHandler = new TestRunEventsHandler(this);
                this.testHostManagerFactoryReady.Wait();
                var testRunCriteriaWithTests =
                    this.dataSerializer.DeserializePayload <TestRunCriteriaWithTests>(message);

                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager()
                    .StartTestRun(
                        testRunCriteriaWithTests.Tests,
                        testRunCriteriaWithTests.Package,
                        testRunCriteriaWithTests.RunSettings,
                        testRunCriteriaWithTests.TestExecutionContext,
                        this.GetTestCaseEventsHandler(testRunCriteriaWithTests.RunSettings),
                        testRunEventsHandler),
                    0);

                break;
            }

            case MessageType.CancelTestRun:
                jobQueue.Pause();
                this.testHostManagerFactoryReady.Wait();
                testHostManagerFactory.GetExecutionManager().Cancel(new TestRunEventsHandler(this));
                break;

            case MessageType.LaunchAdapterProcessWithDebuggerAttachedCallback:
                this.onAckMessageRecieved?.Invoke(message);
                break;

            case MessageType.AbortTestRun:
                jobQueue.Pause();
                this.testHostManagerFactoryReady.Wait();
                testHostManagerFactory.GetExecutionManager().Abort(new TestRunEventsHandler(this));
                break;

            case MessageType.SessionEnd:
            {
                EqtTrace.Info("Session End message received from server. Closing the connection.");
                sessionCompleted.Set();
                this.Close();
                break;
            }

            case MessageType.SessionAbort:
            {
                // Dont do anything for now.
                break;
            }

            default:
            {
                EqtTrace.Info("Invalid Message types");
                break;
            }
            }
        }
Пример #2
0
        public void OnMessageReceived(object sender, MessageReceivedEventArgs messageReceivedArgs)
        {
            var message = this.dataSerializer.DeserializeMessage(messageReceivedArgs.Data);

            if (EqtTrace.IsInfoEnabled)
            {
                EqtTrace.Info("TestRequestHandler.ProcessRequests: received message: {0}", message);
            }

            switch (message.MessageType)
            {
            case MessageType.VersionCheck:
                var version = this.dataSerializer.DeserializePayload <int>(message);
                // choose the highest version that we both support
                var negotiatedVersion = Math.Min(version, highestSupportedVersion);
                // BUT don't choose 3, because protocol version 3 has performance problems in 16.7.1-16.8. Those problems are caused
                // by choosing payloadSerializer instead of payloadSerializer2 for protocol version 3.
                //
                // We cannot just update the code to choose the new serializer, because then that change would apply only to testhost.
                // Testhost is is delivered by Microsoft.NET.Test.SDK nuget package, and can be used with an older vstest.console.
                // An older vstest.console, that supports protocol version 3, would serialize its messages using payloadSerializer,
                // but the fixed testhost would serialize it using payloadSerializer2, resulting in incompatible messages.
                //
                // Instead we must downgrade to protocol version 2 when 3 would be negotiated. Or higher when higher version
                // would be negotiated.
                if (negotiatedVersion != 3)
                {
                    this.protocolVersion = negotiatedVersion;
                }
                else
                {
                    var flag               = Environment.GetEnvironmentVariable("VSTEST_DISABLE_PROTOCOL_3_VERSION_DOWNGRADE");
                    var flagIsEnabled      = flag != null && flag != "0";
                    var dowgradeIsDisabled = flagIsEnabled;
                    if (dowgradeIsDisabled)
                    {
                        this.protocolVersion = negotiatedVersion;
                    }
                    else
                    {
                        this.protocolVersion = 2;
                    }
                }

                // Send the negotiated protocol to request sender
                this.channel.Send(this.dataSerializer.SerializePayload(MessageType.VersionCheck, this.protocolVersion));

                // Can only do this after InitializeCommunication because TestHost cannot "Send Log" unless communications are initialized
                if (!string.IsNullOrEmpty(EqtTrace.LogFile))
                {
                    this.SendLog(TestMessageLevel.Informational, string.Format(CrossPlatResources.TesthostDiagLogOutputFile, EqtTrace.LogFile));
                }
                else if (!string.IsNullOrEmpty(EqtTrace.ErrorOnInitialization))
                {
                    this.SendLog(TestMessageLevel.Warning, EqtTrace.ErrorOnInitialization);
                }
                break;

            case MessageType.DiscoveryInitialize:
            {
                EqtTrace.Info("Discovery Session Initialize.");
                this.testHostManagerFactoryReady.Wait();
                var discoveryEventsHandler     = new TestDiscoveryEventHandler(this);
                var pathToAdditionalExtensions = this.dataSerializer.DeserializePayload <IEnumerable <string> >(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetDiscoveryManager().Initialize(pathToAdditionalExtensions, discoveryEventsHandler), 0);
                break;
            }

            case MessageType.StartDiscovery:
            {
                //System.Diagnostics.Debugger.Launch();
                //System.Diagnostics.Debugger.Break();

                EqtTrace.Info("Discovery started.");
                this.testHostManagerFactoryReady.Wait();
                var discoveryEventsHandler = new TestDiscoveryEventHandler(this);
                var discoveryCriteria      = this.dataSerializer.DeserializePayload <DiscoveryCriteria>(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetDiscoveryManager()
                    .DiscoverTests(discoveryCriteria, discoveryEventsHandler), 0);

                break;
            }

            case MessageType.ExecutionInitialize:
            {
                EqtTrace.Info("Execution Session Initialize.");
                this.testHostManagerFactoryReady.Wait();
                var testInitializeEventsHandler = new TestInitializeEventsHandler(this);
                var pathToAdditionalExtensions  = this.dataSerializer.DeserializePayload <IEnumerable <string> >(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager().Initialize(pathToAdditionalExtensions, testInitializeEventsHandler), 0);
                break;
            }

            case MessageType.StartTestExecutionWithSources:
            {
                EqtTrace.Info("Execution started.");
                var testRunEventsHandler = new TestRunEventsHandler(this);
                this.testHostManagerFactoryReady.Wait();
                var testRunCriteriaWithSources = this.dataSerializer.DeserializePayload <TestRunCriteriaWithSources>(message);
                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager()
                    .StartTestRun(
                        testRunCriteriaWithSources.AdapterSourceMap,
                        testRunCriteriaWithSources.Package,
                        testRunCriteriaWithSources.RunSettings,
                        testRunCriteriaWithSources.TestExecutionContext,
                        this.GetTestCaseEventsHandler(testRunCriteriaWithSources.RunSettings),
                        testRunEventsHandler),
                    0);

                break;
            }

            case MessageType.StartTestExecutionWithTests:
            {
                //System.Diagnostics.Debugger.Launch();
                //System.Diagnostics.Debugger.Break();

                EqtTrace.Info("Execution started.");
                var testRunEventsHandler = new TestRunEventsHandler(this);
                this.testHostManagerFactoryReady.Wait();
                var testRunCriteriaWithTests =
                    this.dataSerializer.DeserializePayload <TestRunCriteriaWithTests>(message);

                jobQueue.QueueJob(
                    () =>
                    testHostManagerFactory.GetExecutionManager()
                    .StartTestRun(
                        testRunCriteriaWithTests.Tests,
                        testRunCriteriaWithTests.Package,
                        testRunCriteriaWithTests.RunSettings,
                        testRunCriteriaWithTests.TestExecutionContext,
                        this.GetTestCaseEventsHandler(testRunCriteriaWithTests.RunSettings),
                        testRunEventsHandler),
                    0);

                break;
            }

            case MessageType.CancelTestRun:
                jobQueue.Pause();
                this.testHostManagerFactoryReady.Wait();
                testHostManagerFactory.GetExecutionManager().Cancel(new TestRunEventsHandler(this));
                break;

            case MessageType.LaunchAdapterProcessWithDebuggerAttachedCallback:
                this.onLaunchAdapterProcessWithDebuggerAttachedAckReceived?.Invoke(message);
                break;

            case MessageType.AttachDebuggerCallback:
                this.onAttachDebuggerAckRecieved?.Invoke(message);
                break;

            case MessageType.AbortTestRun:
                jobQueue.Pause();
                this.testHostManagerFactoryReady.Wait();
                testHostManagerFactory.GetExecutionManager().Abort(new TestRunEventsHandler(this));
                break;

            case MessageType.SessionEnd:
            {
                EqtTrace.Info("Session End message received from server. Closing the connection.");
                sessionCompleted.Set();
                this.Close();
                break;
            }

            case MessageType.SessionAbort:
            {
                // Don't do anything for now.
                break;
            }

            default:
            {
                EqtTrace.Info("Invalid Message types");
                break;
            }
            }
        }