public async Task TestStandardOperation()
        {
            var server = new TestingServer(clientFactory, null);

            using (var serverCts = new CancellationTokenSource())
            {
                var cancellationToken = serverCts.Token;
                var serverTask        = server.RunAsync(cancellationToken);
                try
                {
                    IServerClient adminClient;

                    var giveUpAt = DateTimeOffset.Now.AddSeconds(60);
                    do
                    {
                        try
                        {
                            adminClient = await clientFactory.CreateServerClient(server.Url, User.AdminName, User.DefaultAdminPassword).ConfigureAwait(false);

                            break;
                        }
                        catch (ServiceUnavailableException)
                        {
                            // migrating, to be expected
                            if (DateTimeOffset.Now > giveUpAt)
                            {
                                throw;
                            }
                            await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
                        }
                    } while (true);

                    using (adminClient)
                    {
                        var serverInfo = await adminClient.Version(default).ConfigureAwait(false);
        public async Task TestSwarmSynchronizationAndUpdates()
        {
            // cleanup existing directories
            new TestingServer(null, false).Dispose();

            const string PrivateKey = "adlfj73ywifhks7iwrgfegjs";

            var controllerAddress = new Uri("http://localhost:5011");

            using (var controller = new TestingServer(new SwarmConfiguration
            {
                Address = controllerAddress,
                Identifier = "controller",
                PrivateKey = PrivateKey
            }, false, 5011))
            {
                using var node1 = new TestingServer(new SwarmConfiguration
                {
                    Address           = new Uri("http://localhost:5012"),
                    ControllerAddress = controllerAddress,
                    Identifier        = "node1",
                    PrivateKey        = PrivateKey
                }, false, 5012);
                using var node2 = new TestingServer(new SwarmConfiguration
                {
                    Address           = new Uri("http://localhost:5013"),
                    ControllerAddress = controllerAddress,
                    Identifier        = "node2",
                    PrivateKey        = PrivateKey
                }, false, 5013);
                using var serverCts = new CancellationTokenSource();
                var cancellationToken = serverCts.Token;
                var serverTask        = Task.WhenAll(
                    node1.Run(cancellationToken),
                    node2.Run(cancellationToken),
                    controller.Run(cancellationToken));

                try
                {
                    using var controllerClient = await CreateAdminClient(controller.Url, cancellationToken);

                    using var node1Client = await CreateAdminClient(node1.Url, cancellationToken);

                    using var node2Client = await CreateAdminClient(node2.Url, cancellationToken);

                    var controllerInfo = await controllerClient.ServerInformation(cancellationToken);

                    async Task WaitForSwarmServerUpdate()
                    {
                        ServerInformationResponse serverInformation;

                        do
                        {
                            await Task.Delay(TimeSpan.FromSeconds(10));

                            serverInformation = await node1Client.ServerInformation(cancellationToken);
                        }while (serverInformation.SwarmServers.Count == 1);
                    }
Beispiel #3
0
        public async Task TestUpdateProtocol()
        {
            using var server    = new TestingServer();
            using var serverCts = new CancellationTokenSource();
            var cancellationToken = serverCts.Token;
            var serverTask        = server.Run(cancellationToken);

            try
            {
                var testUpdateVersion = new Version(4, 3, 0);
                using (var adminClient = await CreateAdminClient(server.Url, cancellationToken))
                    //attempt to update to stable
                    await adminClient.Administration.Update(new Administration
                    {
                        NewVersion = testUpdateVersion
                    }, cancellationToken).ConfigureAwait(false);

                //wait up to 3 minutes for the dl and install
                await Task.WhenAny(serverTask, Task.Delay(TimeSpan.FromMinutes(3), cancellationToken)).ConfigureAwait(false);

                Assert.IsTrue(serverTask.IsCompleted, "Server still running!");

                Assert.IsTrue(Directory.Exists(server.UpdatePath), "Update directory not present!");

                var updatedAssemblyPath = Path.Combine(server.UpdatePath, "Tgstation.Server.Host.dll");
                Assert.IsTrue(File.Exists(updatedAssemblyPath), "Updated assembly missing!");

                var updatedAssemblyVersion = FileVersionInfo.GetVersionInfo(updatedAssemblyPath);
                Assert.AreEqual(testUpdateVersion, Version.Parse(updatedAssemblyVersion.FileVersion).Semver());
            }
            catch (RateLimitException)
            {
                if (String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS4_TEST_GITHUB_TOKEN")))
                {
                    throw;
                }

                Assert.Inconclusive("GitHub rate limit hit!");
            }
            finally
            {
                serverCts.Cancel();
                try
                {
                    await serverTask.ConfigureAwait(false);
                }
                catch (OperationCanceledException) { }
                catch (AggregateException ex)
                {
                    if (ex.InnerException is NotSupportedException notSupportedException)
                    {
                        Assert.Inconclusive(notSupportedException.Message);
                    }
                }
            }
            Assert.IsTrue(server.RestartRequested, "Server not requesting restart!");
        }
 public async Task FullMonty()
 {
     using (var server = new TestingServer())
         using (var serverCts = new CancellationTokenSource())
         {
             var serverTask = server.RunAsync(serverCts.Token);
             try
             {
                 using (var adminClient = await clientFactory.CreateServerClient(server.Url, User.AdminName, User.DefaultAdminPassword).ConfigureAwait(false))
                 {
                     var serverInfo = await adminClient.Version(default).ConfigureAwait(false);
        public async Task TestUpdate()
        {
            var updatePathRoot = Path.GetTempFileName();

            File.Delete(updatePathRoot);
            Directory.CreateDirectory(updatePathRoot);
            try
            {
                var updatePath = Path.Combine(updatePathRoot, Guid.NewGuid().ToString());
                var server     = new TestingServer(clientFactory, updatePath);
                using (var serverCts = new CancellationTokenSource())
                {
                    var cancellationToken = serverCts.Token;
                    var serverTask        = server.RunAsync(cancellationToken);
                    try
                    {
                        IServerClient adminClient;

                        var giveUpAt = DateTimeOffset.Now.AddSeconds(60);
                        do
                        {
                            try
                            {
                                adminClient = await clientFactory.CreateServerClient(server.Url, User.AdminName, User.DefaultAdminPassword).ConfigureAwait(false);

                                break;
                            }
                            catch (ServiceUnavailableException)
                            {
                                //migrating, to be expected
                                if (DateTimeOffset.Now > giveUpAt)
                                {
                                    throw;
                                }
                                await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
                            }
                        } while (true);

                        var testUpdateVersion = new Version(4, 0, 0, 6);
                        using (adminClient)
                            //attempt to update to stable
                            await adminClient.Administration.Update(new Administration
                            {
                                NewVersion = testUpdateVersion
                            }, cancellationToken).ConfigureAwait(false);

                        //wait up to 3 minutes for the dl and install
                        await Task.WhenAny(serverTask, Task.Delay(TimeSpan.FromMinutes(3), cancellationToken)).ConfigureAwait(false);

                        Assert.IsTrue(serverTask.IsCompleted, "Sever still running!");

                        Assert.IsTrue(Directory.Exists(updatePath), "Update directory not present!");

                        var updatedAssemblyPath = Path.Combine(updatePath, "Tgstation.Server.Host.dll");
                        Assert.IsTrue(File.Exists(updatedAssemblyPath), "Updated assembly missing!");

                        var updatedAssemblyVersion = FileVersionInfo.GetVersionInfo(updatedAssemblyPath);
                        Assert.AreEqual(testUpdateVersion, Version.Parse(updatedAssemblyVersion.FileVersion));
                    }
                    finally
                    {
                        serverCts.Cancel();
                        try
                        {
                            await serverTask.ConfigureAwait(false);
                        }
                        catch (OperationCanceledException) { }
                    }
                    Assert.IsTrue(server.RestartRequested, "Server not requesting restart!");
                }
            }
            finally
            {
                Directory.Delete(updatePathRoot, true);
            }
        }
        public async Task TestServer()
        {
            var procs = System.Diagnostics.Process.GetProcessesByName("byond");

            if (procs.Any())
            {
                foreach (var proc in procs)
                {
                    proc.Dispose();
                }
                Assert.Inconclusive("Cannot run server test because DreamDaemon will not start headless while the BYOND pager is running!");
            }

            using var server = new TestingServer();

            using var hardTimeoutCts = new CancellationTokenSource();
            hardTimeoutCts.CancelAfter(new TimeSpan(0, 9, 45));
            var hardTimeoutCancellationToken = hardTimeoutCts.Token;

            hardTimeoutCancellationToken.Register(() => Console.WriteLine($"[{DateTimeOffset.Now}] TEST TIMEOUT HARD!"));

            using var softTimeoutCts = CancellationTokenSource.CreateLinkedTokenSource(hardTimeoutCancellationToken);
            softTimeoutCts.CancelAfter(new TimeSpan(0, 9, 15));
            var  softTimeoutCancellationToken = softTimeoutCts.Token;
            bool tooLateForSoftTimeout        = false;

            softTimeoutCancellationToken.Register(() =>
            {
                if (!tooLateForSoftTimeout)
                {
                    Console.WriteLine($"[{DateTimeOffset.Now}] TEST TIMEOUT SOFT!");
                }
            });

            using var serverCts = CancellationTokenSource.CreateLinkedTokenSource(softTimeoutCancellationToken);
            var cancellationToken = serverCts.Token;

            TerminateAllDDs();
            var serverTask = server.Run(cancellationToken);

            try
            {
                async Task <IServerClient> CreateAdminClient()
                {
                    var giveUpAt = DateTimeOffset.Now.AddSeconds(60);

                    do
                    {
                        try
                        {
                            return(await clientFactory.CreateFromLogin(server.Url, User.AdminName, User.DefaultAdminPassword, attemptLoginRefresh : false).ConfigureAwait(false));
                        }
                        catch (HttpRequestException)
                        {
                            //migrating, to be expected
                            if (DateTimeOffset.Now > giveUpAt)
                            {
                                throw;
                            }
                            await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
                        }
                        catch (ServiceUnavailableException)
                        {
                            // migrating, to be expected
                            if (DateTimeOffset.Now > giveUpAt)
                            {
                                throw;
                            }
                            await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
                        }
                    } while (true);
                }

                Api.Models.Instance instance;
                using (var adminClient = await CreateAdminClient())
                {
                    if (server.DumpOpenApiSpecpath)
                    {
                        // Dump swagger to disk
                        // This is purely for CI
                        var webRequest = WebRequest.Create(server.Url.ToString() + "swagger/v1/swagger.json");
                        using var response = webRequest.GetResponse();
                        using var content  = response.GetResponseStream();
                        using var output   = new FileStream(@"C:\swagger.json", FileMode.Create);
                        await content.CopyToAsync(output);
                    }

                    var serverInfo = await adminClient.Version(default).ConfigureAwait(false);
        public async Task TestUpdateProtocolAndDisabledOAuth()
        {
            using var server    = new TestingServer(null, false);
            using var serverCts = new CancellationTokenSource();
            var cancellationToken = serverCts.Token;
            var serverTask        = server.Run(cancellationToken);

            try
            {
                var testUpdateVersion = new Version(4, 3, 0);
                using (var adminClient = await CreateAdminClient(server.Url, cancellationToken))
                {
                    // Disabled OAuth test
                    using (var httpClient = new HttpClient())
                        using (var request = new HttpRequestMessage(HttpMethod.Post, server.Url.ToString()))
                        {
                            request.Headers.Accept.Clear();
                            request.Headers.UserAgent.Add(new ProductInfoHeaderValue("RootTest", "1.0.0"));
                            request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Json));
                            request.Headers.Add(ApiHeaders.ApiVersionHeader, "Tgstation.Server.Api/" + ApiHeaders.Version);
                            request.Headers.Authorization = new AuthenticationHeaderValue(ApiHeaders.OAuthAuthenticationScheme, adminClient.Token.Bearer);
                            request.Headers.Add(ApiHeaders.OAuthProviderHeader, OAuthProvider.GitHub.ToString());
                            using var response = await httpClient.SendAsync(request, cancellationToken);

                            Assert.AreEqual(HttpStatusCode.BadRequest, response.StatusCode);
                            var content = await response.Content.ReadAsStringAsync();

                            var message = JsonConvert.DeserializeObject <ErrorMessageResponse>(content);
                            Assert.AreEqual(ErrorCode.OAuthProviderDisabled, message.ErrorCode);
                        }

                    //attempt to update to stable
                    await adminClient.Administration.Update(new ServerUpdateRequest
                    {
                        NewVersion = testUpdateVersion
                    }, cancellationToken).ConfigureAwait(false);

                    var serverInfo = await adminClient.ServerInformation(cancellationToken);

                    Assert.IsTrue(serverInfo.UpdateInProgress);
                }

                //wait up to 3 minutes for the dl and install
                await Task.WhenAny(serverTask, Task.Delay(TimeSpan.FromMinutes(3), cancellationToken)).ConfigureAwait(false);

                Assert.IsTrue(serverTask.IsCompleted, "Server still running!");

                Assert.IsTrue(Directory.Exists(server.UpdatePath), "Update directory not present!");

                var updatedAssemblyPath = Path.Combine(server.UpdatePath, "Tgstation.Server.Host.dll");
                Assert.IsTrue(File.Exists(updatedAssemblyPath), "Updated assembly missing!");

                var updatedAssemblyVersion = FileVersionInfo.GetVersionInfo(updatedAssemblyPath);
                Assert.AreEqual(testUpdateVersion, Version.Parse(updatedAssemblyVersion.FileVersion).Semver());
            }
            catch (RateLimitException ex)
            {
                if (String.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("TGS4_TEST_GITHUB_TOKEN")))
                {
                    throw;
                }

                Assert.Inconclusive("GitHub rate limit hit: {0}", ex);
            }
            finally
            {
                serverCts.Cancel();
                try
                {
                    await serverTask.ConfigureAwait(false);
                }
                catch (OperationCanceledException) { }
                catch (AggregateException ex)
                {
                    if (ex.InnerException is NotSupportedException notSupportedException)
                    {
                        Assert.Inconclusive(notSupportedException.Message);
                    }
                }
            }
            Assert.IsTrue(server.RestartRequested, "Server not requesting restart!");
        }