Пример #1
0
        internal static ServerData CreateServer(
            string pipeName = null,
            TimeSpan? timeout = null,
            ICompilerServerHost compilerServerHost = null)
        {
            pipeName = pipeName ?? Guid.NewGuid().ToString();
            compilerServerHost = compilerServerHost ?? new DesktopCompilerServerHost(DefaultClientDirectory, DefaultSdkDirectory);

            var taskSource = new TaskCompletionSource<ServerStats>();
            var cts = new CancellationTokenSource();
            var thread = new Thread(_ =>
            {
                var listener = new TestableDiagnosticListener();
                try
                {
                    var clientConnectionHost = new NamedPipeClientConnectionHost(compilerServerHost, pipeName);
                    var mutexName = BuildProtocolConstants.GetServerMutexName(pipeName);
                    VBCSCompiler.Run(
                        mutexName,
                        clientConnectionHost,
                        listener,
                        timeout ?? TimeSpan.FromMilliseconds(-1),
                        cts.Token);
                }
                finally
                {
                    var serverStats = new ServerStats(connections: listener.ConnectionCount, completedConnections: listener.CompletedCount);
                    taskSource.SetResult(serverStats);
                }
            });

            thread.Start();

            return new ServerData(cts, taskSource.Task, pipeName);
        }
Пример #2
0
        public async Task FirstClientCanOverrideDefaultTimeout()
        {
            var      cts                = new CancellationTokenSource();
            var      listener           = new TestableDiagnosticListener();
            TimeSpan?newTimeSpan        = null;
            var      connectionSource   = new TaskCompletionSource <int>();
            var      diagnosticListener = new Mock <IDiagnosticListener>();

            diagnosticListener
            .Setup(x => x.UpdateKeepAlive(It.IsAny <TimeSpan>()))
            .Callback <TimeSpan>(ts => { newTimeSpan = ts; });
            diagnosticListener
            .Setup(x => x.ConnectionProcessed(It.IsAny <int>()))
            .Callback <int>(count => connectionSource.SetResult(count));

            var pipeName       = Guid.NewGuid().ToString();
            var dispatcherTask = Task.Run(() =>
            {
                var dispatcher = new ServerDispatcher(CreateNopRequestHandler().Object, diagnosticListener.Object);
                dispatcher.ListenAndDispatchConnections(pipeName, TimeSpan.FromSeconds(1), cancellationToken: cts.Token);
            });

            var seconds  = 10;
            var response = await RunCSharpCompile(pipeName, HelloWorldSourceText, TimeSpan.FromSeconds(seconds)).ConfigureAwait(false);

            Assert.Equal(BuildResponse.ResponseType.Completed, response.Type);
            Assert.Equal(1, await connectionSource.Task.ConfigureAwait(false));
            Assert.True(newTimeSpan.HasValue);
            Assert.Equal(seconds, newTimeSpan.Value.TotalSeconds);

            cts.Cancel();
            await dispatcherTask.ConfigureAwait(false);
        }
Пример #3
0
        public async Task KeepAliveAfterSimultaneousConnection()
        {
            var keepAlive      = TimeSpan.FromSeconds(1);
            var listener       = new TestableDiagnosticListener();
            var pipeName       = Guid.NewGuid().ToString();
            var dispatcherTask = Task.Run(() =>
            {
                var dispatcher = new ServerDispatcher(new CompilerRequestHandler(Temp.CreateDirectory().Path), listener);
                dispatcher.ListenAndDispatchConnections(pipeName, keepAlive);
            });

            var list = new List <Task>();

            for (int i = 0; i < 5; i++)
            {
                var task = Task.Run(() => RunCSharpCompile(pipeName, HelloWorldSourceText));
                list.Add(task);
            }

            foreach (var current in list)
            {
                await current.ConfigureAwait(false);
            }

            await dispatcherTask.ConfigureAwait(false);

            Assert.Equal(5, listener.ProcessedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True((DateTime.Now - listener.LastProcessedTime.Value) > keepAlive);
        }
Пример #4
0
        internal static async Task <ServerData> CreateServer(
            string pipeName = null,
            ICompilerServerHost compilerServerHost = null,
            bool failingServer = false,
            string tempPath    = null)
        {
            // The total pipe path must be < 92 characters on Unix, so trim this down to 10 chars
            pipeName           = pipeName ?? Guid.NewGuid().ToString().Substring(0, 10);
            compilerServerHost = compilerServerHost ?? BuildServerController.CreateCompilerServerHost();
            tempPath           = tempPath ?? Path.GetTempPath();
            var clientConnectionHost = BuildServerController.CreateClientConnectionHostForServerHost(compilerServerHost, pipeName);

            if (failingServer)
            {
                clientConnectionHost = new FailingClientConnectionHost(clientConnectionHost);
            }

            var serverStatsSource  = new TaskCompletionSource <ServerStats>();
            var serverListenSource = new TaskCompletionSource <bool>();
            var cts       = new CancellationTokenSource();
            var mutexName = BuildServerConnection.GetServerMutexName(pipeName);
            var listener  = new TestableDiagnosticListener();
            var task      = Task.Run(() =>
            {
                listener.Listening += (sender, e) => { serverListenSource.TrySetResult(true); };
                try
                {
                    BuildServerController.CreateAndRunServer(
                        pipeName,
                        tempPath,
                        clientConnectionHost,
                        listener,
                        keepAlive: TimeSpan.FromMilliseconds(-1),
                        cancellationToken: cts.Token);
                }
                finally
                {
                    var serverStats = new ServerStats(connections: listener.ConnectionCount, completedConnections: listener.CompletedCount);
                    serverStatsSource.SetResult(serverStats);
                }
            });

            // The contract of this function is that it will return once the server has started.  Spin here until
            // we can verify the server has started or simply failed to start.
            while (BuildServerConnection.WasServerMutexOpen(mutexName) != true && !task.IsCompleted)
            {
                await Task.Yield();
            }

            if (task.IsFaulted)
            {
                throw task.Exception;
            }

            return(new ServerData(cts, pipeName, serverStatsSource.Task, serverListenSource.Task, listener.ConnectionCompletedCollection));
        }
        internal static ServerData CreateServer(
            string pipeName = null,
            ICompilerServerHost compilerServerHost = null,
            bool failingServer = false)
        {
            pipeName           = pipeName ?? Guid.NewGuid().ToString();
            compilerServerHost = compilerServerHost ?? DesktopBuildServerController.CreateCompilerServerHost();
            var clientConnectionHost = DesktopBuildServerController.CreateClientConnectionHostForServerHost(compilerServerHost, pipeName);

            if (failingServer)
            {
                clientConnectionHost = new FailingClientConnectionHost(clientConnectionHost);
            }

            var serverStatsSource  = new TaskCompletionSource <ServerStats>();
            var serverListenSource = new TaskCompletionSource <bool>();
            var cts       = new CancellationTokenSource();
            var mutexName = BuildServerConnection.GetServerMutexName(pipeName);
            var thread    = new Thread(_ =>
            {
                var listener        = new TestableDiagnosticListener();
                listener.Listening += (sender, e) => { serverListenSource.TrySetResult(true); };
                try
                {
                    DesktopBuildServerController.RunServer(
                        pipeName,
                        clientConnectionHost,
                        listener,
                        keepAlive: TimeSpan.FromMilliseconds(-1),
                        cancellationToken: cts.Token);
                }
                finally
                {
                    var serverStats = new ServerStats(connections: listener.ConnectionCount, completedConnections: listener.CompletedCount);
                    serverStatsSource.SetResult(serverStats);
                }
            });

            thread.Start();

            // The contract of this function is that it will return once the server has started.  Spin here until
            // we can verify the server has started or simply failed to start.
            while (BuildServerConnection.WasServerMutexOpen(mutexName) != true && thread.IsAlive)
            {
                Thread.Yield();
            }

            return(new ServerData(cts, pipeName, serverStatsSource.Task, serverListenSource.Task));
        }
Пример #6
0
        internal static async Task <ServerData> CreateServer(
            string pipeName = null,
            ICompilerServerHost compilerServerHost     = null,
            IClientConnectionHost clientConnectionHost = null,
            TimeSpan?keepAlive = null)
        {
            // The total pipe path must be < 92 characters on Unix, so trim this down to 10 chars
            pipeName ??= Guid.NewGuid().ToString().Substring(0, 10);
            compilerServerHost ??= BuildServerController.CreateCompilerServerHost();
            clientConnectionHost ??= BuildServerController.CreateClientConnectionHost(pipeName);
            keepAlive ??= TimeSpan.FromMilliseconds(-1);

            var listener = new TestableDiagnosticListener();
            var listenerTaskCompletionSource = new TaskCompletionSource <TestableDiagnosticListener>();
            var serverListenSource           = new TaskCompletionSource <bool>();
            var cts       = new CancellationTokenSource();
            var mutexName = BuildServerConnection.GetServerMutexName(pipeName);
            var task      = Task.Run(() =>
            {
                try
                {
                    BuildServerController.CreateAndRunServer(
                        pipeName,
                        compilerServerHost,
                        clientConnectionHost,
                        listener,
                        keepAlive: keepAlive,
                        cancellationToken: cts.Token);
                }
                finally
                {
                    listenerTaskCompletionSource.SetResult(listener);
                }
            });

            // The contract of this function is that it will return once the server has started.  Spin here until
            // we can verify the server has started or simply failed to start.
            while (BuildServerConnection.WasServerMutexOpen(mutexName) != true && !task.IsCompleted)
            {
                await Task.Yield();
            }

            if (task.IsFaulted)
            {
                throw task.Exception;
            }

            return(new ServerData(cts, pipeName, listenerTaskCompletionSource.Task));
        }
Пример #7
0
        public void KeepAliveAfterSingleConnection()
        {
            var connection = CreateClientConnection(CompletionReason.CompilationCompleted);
            var host       = CreateClientConnectionHost(
                Task.FromResult(connection),
                new TaskCompletionSource <IClientConnection>().Task);
            var listener   = new TestableDiagnosticListener();
            var keepAlive  = TimeSpan.FromSeconds(1);
            var dispatcher = new ServerDispatcher(host, listener);

            dispatcher.ListenAndDispatchConnections(keepAlive);

            Assert.Equal(1, listener.CompletedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True(listener.HitKeepAliveTimeout);
        }
Пример #8
0
        public void KeepAliveNoConnections()
        {
            var keepAlive      = TimeSpan.FromSeconds(3);
            var connectionHost = new Mock <IClientConnectionHost>();

            connectionHost
            .Setup(x => x.CreateListenTask(It.IsAny <CancellationToken>()))
            .Returns(new TaskCompletionSource <IClientConnection>().Task);

            var listener   = new TestableDiagnosticListener();
            var dispatcher = new ServerDispatcher(connectionHost.Object, listener);
            var startTime  = DateTime.Now;

            dispatcher.ListenAndDispatchConnections(keepAlive);

            Assert.True(listener.HitKeepAliveTimeout);
        }
Пример #9
0
        public async Task KeepAliveAfterSimultaneousConnection()
        {
            var totalCount  = 2;
            var readySource = new TaskCompletionSource <bool>();
            var list        = new List <TaskCompletionSource <ConnectionData> >();
            var host        = new Mock <IClientConnectionHost>();

            host
            .Setup(x => x.CreateListenTask(It.IsAny <CancellationToken>()))
            .Returns((CancellationToken ct) =>
            {
                if (list.Count < totalCount)
                {
                    var source = new TaskCompletionSource <ConnectionData>();
                    var client = CreateClientConnection(source.Task);
                    list.Add(source);
                    return(Task.FromResult(client));
                }

                readySource.SetResult(true);
                return(new TaskCompletionSource <IClientConnection>().Task);
            });

            var keepAlive      = TimeSpan.FromSeconds(1);
            var listener       = new TestableDiagnosticListener();
            var dispatcherTask = Task.Run(() =>
            {
                var dispatcher = new ServerDispatcher(host.Object, listener);
                dispatcher.ListenAndDispatchConnections(keepAlive);
            });


            await readySource.Task.ConfigureAwait(true);

            foreach (var source in list)
            {
                source.SetResult(new ConnectionData(CompletionReason.Completed));
            }

            await dispatcherTask.ConfigureAwait(true);

            Assert.Equal(totalCount, listener.ProcessedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True(listener.HitKeepAliveTimeout);
        }
Пример #10
0
        public async Task KeepAliveAfterSingleConnection()
        {
            var keepAlive      = TimeSpan.FromSeconds(1);
            var listener       = new TestableDiagnosticListener();
            var pipeName       = Guid.NewGuid().ToString();
            var dispatcherTask = Task.Run(() =>
            {
                var dispatcher = new ServerDispatcher(CreateNopRequestHandler().Object, listener);
                dispatcher.ListenAndDispatchConnections(pipeName, keepAlive);
            });

            await RunCSharpCompile(pipeName, HelloWorldSourceText).ConfigureAwait(false);

            await dispatcherTask.ConfigureAwait(false);

            Assert.Equal(1, listener.ProcessedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True((DateTime.Now - listener.LastProcessedTime.Value) > keepAlive);
        }
Пример #11
0
        internal static ServerData CreateServer(
            string pipeName  = null,
            TimeSpan?timeout = null,
            ICompilerServerHost compilerServerHost     = null,
            IClientConnectionHost clientConnectionHost = null)
        {
            pipeName           = pipeName ?? Guid.NewGuid().ToString();
            compilerServerHost = compilerServerHost ?? new DesktopCompilerServerHost(DefaultClientDirectory, DefaultSdkDirectory);

            var serverStatsSource  = new TaskCompletionSource <ServerStats>();
            var serverListenSource = new TaskCompletionSource <bool>();
            var cts    = new CancellationTokenSource();
            var thread = new Thread(_ =>
            {
                var listener        = new TestableDiagnosticListener();
                listener.Listening += (sender, e) => { serverListenSource.TrySetResult(true); };
                try
                {
                    clientConnectionHost = clientConnectionHost ?? new NamedPipeClientConnectionHost(compilerServerHost, pipeName);

                    var mutexName = BuildProtocolConstants.GetServerMutexName(pipeName);
                    VBCSCompiler.Run(
                        mutexName,
                        clientConnectionHost,
                        listener,
                        timeout ?? TimeSpan.FromMilliseconds(-1),
                        cts.Token);
                }
                finally
                {
                    var serverStats = new ServerStats(connections: listener.ConnectionCount, completedConnections: listener.CompletedCount);
                    serverStatsSource.SetResult(serverStats);
                }
            });

            thread.Start();

            return(new ServerData(cts, pipeName, serverStatsSource.Task, serverListenSource.Task));
        }
Пример #12
0
        public void KeepAliveAfterMultipleConnection()
        {
            var count = 5;
            var list  = new List <Task <IClientConnection> >();

            for (var i = 0; i < count; i++)
            {
                var connection = CreateClientConnection(CompletionReason.CompilationCompleted);
                list.Add(Task.FromResult(connection));
            }

            list.Add(new TaskCompletionSource <IClientConnection>().Task);
            var host       = CreateClientConnectionHost(list.ToArray());
            var listener   = new TestableDiagnosticListener();
            var keepAlive  = TimeSpan.FromSeconds(1);
            var dispatcher = new ServerDispatcher(host, listener);

            dispatcher.ListenAndDispatchConnections(keepAlive);

            Assert.Equal(count, listener.CompletedCount);
            Assert.True(listener.LastProcessedTime.HasValue);
            Assert.True(listener.HitKeepAliveTimeout);
        }
Пример #13
0
        public void ClientExceptionShouldBeginShutdown()
        {
            var client = new Mock <IClientConnection>();

            client
            .Setup(x => x.HandleConnection(It.IsAny <bool>(), It.IsAny <CancellationToken>()))
            .Throws(new Exception());

            var listenCancellationToken = default(CancellationToken);
            var first = true;

            var host = new Mock <IClientConnectionHost>();

            host
            .Setup(x => x.CreateListenTask(It.IsAny <CancellationToken>()))
            .Returns((CancellationToken cancellationToken) =>
            {
                if (first)
                {
                    first = false;
                    return(Task.FromResult(client.Object));
                }
                else
                {
                    listenCancellationToken = cancellationToken;
                    return(Task.Delay(-1, cancellationToken).ContinueWith <IClientConnection>(_ => null, TaskScheduler.Default));
                }
            });

            var listener   = new TestableDiagnosticListener();
            var dispatcher = new ServerDispatcher(host.Object, listener);

            dispatcher.ListenAndDispatchConnections(TimeSpan.FromSeconds(10));

            Assert.True(listener.HasDetectedBadConnection);
            Assert.True(listenCancellationToken.IsCancellationRequested);
        }
Пример #14
0
        internal static ServerData CreateServer(
            string pipeName = null,
            TimeSpan? timeout = null,
            ICompilerServerHost compilerServerHost = null,
            IClientConnectionHost clientConnectionHost = null)
        {
            pipeName = pipeName ?? Guid.NewGuid().ToString();
            compilerServerHost = compilerServerHost ?? new DesktopCompilerServerHost(DefaultClientDirectory, DefaultSdkDirectory);

            var serverStatsSource = new TaskCompletionSource<ServerStats>();
            var serverListenSource = new TaskCompletionSource<bool>();
            var cts = new CancellationTokenSource();
            var mutexName = DesktopBuildClient.GetServerMutexName(pipeName);
            var thread = new Thread(_ =>
            {
                var listener = new TestableDiagnosticListener();
                listener.Listening += (sender, e) => { serverListenSource.TrySetResult(true); };
                try
                {
                    clientConnectionHost = clientConnectionHost ?? new NamedPipeClientConnectionHost(compilerServerHost, pipeName);

                    DesktopBuildServerController.RunServer(
                        pipeName,
                        clientConnectionHost,
                        listener,
                        timeout ?? TimeSpan.FromMilliseconds(-1),
                        cts.Token);
                }
                finally
                {
                    var serverStats = new ServerStats(connections: listener.ConnectionCount, completedConnections: listener.CompletedCount);
                    serverStatsSource.SetResult(serverStats);
                }
            });

            thread.Start();

            // The contract of this function is that it will return once the server has started.  Spin here until
            // we can verify the server has started or simply failed to start.
            while (DesktopBuildClient.WasServerMutexOpen(mutexName) != true && thread.IsAlive)
            {
                Thread.Yield();
            }

            return new ServerData(cts, pipeName, serverStatsSource.Task, serverListenSource.Task);
        }