public async Task NoServerMutex()
            {
                var pipeName = Guid.NewGuid().ToString();
                var exitCode = await VBCSCompiler.RunShutdownAsync(pipeName, waitForProcess : false).ConfigureAwait(false);

                Assert.Equal(CommonCompiler.Succeeded, exitCode);
            }
Beispiel #2
0
        public void MutexAcquiredWhenRunningServer()
        {
            var mutexName = Guid.NewGuid().ToString("N");
            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;
                    Assert.True(Mutex.TryOpenExisting(mutexName, out mutex));
                    Assert.False(mutex.WaitOne(millisecondsTimeout: 0));
                    source.SetResult(true);
                });

                // 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 = VBCSCompiler.Run(mutexName, host.Object, keepAlive: TimeSpan.FromSeconds(1));

            Assert.Equal(CommonCompiler.Succeeded, result);
        }
Beispiel #3
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));
        }
            public async Task Standard()
            {
                using (var serverData = ServerUtil.CreateServer())
                {
                    // Make sure the server is listening for this particular test.
                    await serverData.ListenTask;
                    var exitCode = await VBCSCompiler.RunShutdownAsync(serverData.PipeName, waitForProcess : false).ConfigureAwait(false);

                    Assert.Equal(CommonCompiler.Succeeded, exitCode);
                    await serverData.Verify(connections : 1, completed : 1);
                }
            }
Beispiel #5
0
            private Task CreateServerCore(string pipeName)
            {
                Action action = () =>
                {
                    var compilerServerHost   = new DesktopCompilerServerHost(ClientDirectory, SdkDirectory);
                    var clientConnectionHost = new NamedPipeClientConnectionHost(compilerServerHost, pipeName);
                    var mutexName            = $"{pipeName}.server";
                    VBCSCompiler.Run(mutexName, clientConnectionHost, TimeSpan.FromSeconds(3));
                };

                var task = new Task(action, TaskCreationOptions.LongRunning);

                task.Start(TaskScheduler.Default);
                return(task);
            }
            public async Task ServerShutdownsDuringProcessing()
            {
                using (var readyMre = new ManualResetEvent(initialState: false))
                    using (var doneMre = new ManualResetEvent(initialState: false))
                    {
                        var  pipeName  = Guid.NewGuid().ToString();
                        var  mutexName = BuildProtocolConstants.GetServerMutexName(pipeName);
                        bool created   = false;
                        bool connected = false;

                        var thread = new Thread(() =>
                        {
                            using (var stream = new NamedPipeServerStream(pipeName))
                            {
                                var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created);
                                readyMre.Set();

                                stream.WaitForConnection();
                                connected = true;

                                // Client is waiting for a response.  Close the mutex now.  Then close the connection
                                // so the client gets an error.
                                mutex.ReleaseMutex();
                                mutex.Dispose();
                                stream.Close();

                                doneMre.WaitOne();
                            }
                        });

                        // Block until the mutex and named pipe is setup.
                        thread.Start();
                        readyMre.WaitOne();

                        var exitCode = await VBCSCompiler.RunShutdownAsync(pipeName, waitForProcess : false);

                        // Let the fake server exit.
                        doneMre.Set();
                        thread.Join();

                        Assert.Equal(CommonCompiler.Succeeded, exitCode);
                        Assert.True(connected);
                        Assert.True(created);
                    }
            }
            public async Task NoServerConnection()
            {
                using (var readyMre = new ManualResetEvent(initialState: false))
                    using (var doneMre = new ManualResetEvent(initialState: false))
                    {
                        var  pipeName  = Guid.NewGuid().ToString();
                        var  mutexName = BuildProtocolConstants.GetServerMutexName(pipeName);
                        bool created   = false;
                        bool connected = false;

                        var thread = new Thread(() =>
                        {
                            using (var mutex = new Mutex(initiallyOwned: true, name: mutexName, createdNew: out created))
                                using (var stream = new NamedPipeServerStream(pipeName))
                                {
                                    readyMre.Set();

                                    // Get a client connection and then immediately close it.  Don't give any response.
                                    stream.WaitForConnection();
                                    connected = true;
                                    stream.Close();

                                    doneMre.WaitOne();
                                    mutex.ReleaseMutex();
                                }
                        });

                        // Block until the mutex and named pipe is setup.
                        thread.Start();
                        readyMre.WaitOne();

                        var exitCode = await VBCSCompiler.RunShutdownAsync(pipeName, waitForProcess : false);

                        // Let the fake server exit.
                        doneMre.Set();
                        thread.Join();

                        Assert.Equal(CommonCompiler.Failed, exitCode);
                        Assert.True(connected);
                        Assert.True(created);
                    }
            }
Beispiel #8
0
        public void MutexStopsServerStarting()
        {
            var mutexName = Guid.NewGuid().ToString("N");

            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 = VBCSCompiler.Run(mutexName, host.Object, keepAlive: null);
                    Assert.Equal(CommonCompiler.Failed, result);
                }
                finally
                {
                    mutex.ReleaseMutex();
                }
            }
        }
 private bool Parse(params string[] args)
 {
     return(VBCSCompiler.ParseCommandLine(args, out _pipeName, out _shutdown));
 }