Пример #1
0
        public void MutexStopsServerStarting()
        {
            var pipeName  = Guid.NewGuid().ToString("N");
            var mutexName = BuildServerConnection.GetServerMutexName(pipeName);

            bool holdsMutex;

            using (var mutex = new Mutex(initiallyOwned: true,
                                         name: mutexName,
                                         createdNew: out holdsMutex))
            {
                Assert.True(holdsMutex);
                try
                {
                    var host   = new Mock <IClientConnectionHost>(MockBehavior.Strict);
                    var result = DesktopBuildServerController.RunServer(
                        pipeName,
                        Path.GetTempPath(),
                        host.Object,
                        keepAlive: null);
                    Assert.Equal(CommonCompiler.Failed, result);
                }
                finally
                {
                    mutex.ReleaseMutex();
                }
            }
        }
Пример #2
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 ?? DesktopBuildServerController.CreateCompilerServerHost();
            tempPath           = tempPath ?? Path.GetTempPath();
            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 task      = Task.Run(() =>
            {
                var listener        = new TestableDiagnosticListener();
                listener.Listening += (sender, e) => { serverListenSource.TrySetResult(true); };
                try
                {
                    DesktopBuildServerController.RunServer(
                        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));
        }
Пример #3
0
        public void RunServerWithLongTempPath()
        {
            var pipeName = Guid.NewGuid().ToString("N");
            // Make a really long path. This should work on Windows, which doesn't rely on temp path,
            // but not on Unix, which has a max path length
            var tempPath = new string('a', 100);

            // This test fails by spinning forever. If the path is not seen as invalid, the server
            // starts up and will never return.
            Assert.Equal(CommonCompiler.Failed, DesktopBuildServerController.RunServer(pipeName, tempPath: tempPath));
        }
Пример #4
0
        public void MutexAcquiredWhenRunningServer()
        {
            var pipeName  = Guid.NewGuid().ToString("N");
            var mutexName = BuildServerConnection.GetServerMutexName(pipeName);
            var host      = new Mock <IClientConnectionHost>(MockBehavior.Strict);

            host
            .Setup(x => x.CreateListenTask(It.IsAny <CancellationToken>()))
            .Returns(() =>
            {
                // Use a thread instead of Task to guarantee this code runs on a different
                // thread and we can validate the mutex state.
                var source = new TaskCompletionSource <bool>();
                var thread = new Thread(_ =>
                {
                    Mutex mutex = null;
                    try
                    {
                        Assert.True(Mutex.TryOpenExisting(mutexName, out mutex));
                        Assert.False(mutex.WaitOne(millisecondsTimeout: 0));
                        source.SetResult(true);
                    }
                    catch (Exception ex)
                    {
                        source.SetException(ex);
                        throw;
                    }
                    finally
                    {
                        mutex?.Dispose();
                    }
                });

                // Synchronously wait here.  Don't returned a Task value because we need to
                // ensure the above check completes before the server hits a timeout and
                // releases the mutex.
                thread.Start();
                source.Task.Wait();

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

            var result = DesktopBuildServerController.RunServer(
                pipeName,
                Path.GetTempPath(),
                host.Object,
                keepAlive: TimeSpan.FromSeconds(1));

            Assert.Equal(CommonCompiler.Succeeded, result);
        }
        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));
        }