From 19190e79b105efc72366a0f2ad050773a102fa53 Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Mon, 9 Mar 2020 14:09:16 -0700 Subject: [PATCH] Add frontend-backend test (#89) --- samples/frontend-backend/backend/Program.cs | 2 +- samples/frontend-backend/backend/Startup.cs | 4 +- .../frontend/ConfigurationExtensions.cs | 2 +- samples/frontend-backend/frontend/Program.cs | 2 +- samples/frontend-backend/frontend/Startup.cs | 4 +- samples/multi-project/backend/Program.cs | 2 +- samples/multi-project/backend/Startup.cs | 4 +- .../frontend/ConfigurationExtensions.cs | 2 +- .../frontend/Pages/Error.cshtml.cs | 2 +- samples/multi-project/frontend/Program.cs | 2 +- samples/multi-project/frontend/Startup.cs | 4 +- samples/multi-project/worker/Program.cs | 2 +- samples/multi-project/worker/QueueWorker.cs | 4 +- .../single-project/test-project/Program.cs | 2 +- .../single-project/test-project/Startup.cs | 2 +- test/E2ETest/TyeRunTests.cs | 85 ++++++++++++++++++- 16 files changed, 104 insertions(+), 21 deletions(-) diff --git a/samples/frontend-backend/backend/Program.cs b/samples/frontend-backend/backend/Program.cs index 8fa1a574..3dade96b 100644 --- a/samples/frontend-backend/backend/Program.cs +++ b/samples/frontend-backend/backend/Program.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/samples/frontend-backend/backend/Startup.cs b/samples/frontend-backend/backend/Startup.cs index 006b5355..079a752f 100644 --- a/samples/frontend-backend/backend/Startup.cs +++ b/samples/frontend-backend/backend/Startup.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -13,7 +13,7 @@ using Microsoft.Extensions.Hosting; namespace Backend { public class Startup - { + { private readonly JsonSerializerOptions options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true, diff --git a/samples/frontend-backend/frontend/ConfigurationExtensions.cs b/samples/frontend-backend/frontend/ConfigurationExtensions.cs index ff49daa0..92ddedbe 100644 --- a/samples/frontend-backend/frontend/ConfigurationExtensions.cs +++ b/samples/frontend-backend/frontend/ConfigurationExtensions.cs @@ -22,4 +22,4 @@ namespace Microsoft.Extensions.Configuration return new Uri(protocol + "://" + host + ":" + port + "/"); } } -} \ No newline at end of file +} diff --git a/samples/frontend-backend/frontend/Program.cs b/samples/frontend-backend/frontend/Program.cs index 0ec50afe..34ab1820 100644 --- a/samples/frontend-backend/frontend/Program.cs +++ b/samples/frontend-backend/frontend/Program.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/samples/frontend-backend/frontend/Startup.cs b/samples/frontend-backend/frontend/Startup.cs index 81e7627d..23447056 100644 --- a/samples/frontend-backend/frontend/Startup.cs +++ b/samples/frontend-backend/frontend/Startup.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -64,7 +64,7 @@ namespace Frontend await context.Response.WriteAsync($"Backend Listening IP: {backendInfo.IP}{Environment.NewLine}"); await context.Response.WriteAsync($"Backend Hostname: {backendInfo.Hostname}{Environment.NewLine}"); }); - + endpoints.MapHealthChecks("/healthz"); }); } diff --git a/samples/multi-project/backend/Program.cs b/samples/multi-project/backend/Program.cs index 96f72093..f7790a1a 100644 --- a/samples/multi-project/backend/Program.cs +++ b/samples/multi-project/backend/Program.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/samples/multi-project/backend/Startup.cs b/samples/multi-project/backend/Startup.cs index 3d1e32c1..bd627038 100644 --- a/samples/multi-project/backend/Startup.cs +++ b/samples/multi-project/backend/Startup.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -21,7 +21,7 @@ namespace Backend } public IConfiguration Configuration { get; } - + public void ConfigureServices(IServiceCollection services) { services.AddAuthorization(); diff --git a/samples/multi-project/frontend/ConfigurationExtensions.cs b/samples/multi-project/frontend/ConfigurationExtensions.cs index ff49daa0..92ddedbe 100644 --- a/samples/multi-project/frontend/ConfigurationExtensions.cs +++ b/samples/multi-project/frontend/ConfigurationExtensions.cs @@ -22,4 +22,4 @@ namespace Microsoft.Extensions.Configuration return new Uri(protocol + "://" + host + ":" + port + "/"); } } -} \ No newline at end of file +} diff --git a/samples/multi-project/frontend/Pages/Error.cshtml.cs b/samples/multi-project/frontend/Pages/Error.cshtml.cs index 02ce3fe5..584be0a2 100644 --- a/samples/multi-project/frontend/Pages/Error.cshtml.cs +++ b/samples/multi-project/frontend/Pages/Error.cshtml.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/samples/multi-project/frontend/Program.cs b/samples/multi-project/frontend/Program.cs index 14849912..d5277964 100644 --- a/samples/multi-project/frontend/Program.cs +++ b/samples/multi-project/frontend/Program.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/samples/multi-project/frontend/Startup.cs b/samples/multi-project/frontend/Startup.cs index 195a2929..ea7cc835 100644 --- a/samples/multi-project/frontend/Startup.cs +++ b/samples/multi-project/frontend/Startup.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -21,7 +21,7 @@ namespace Frontend } public IConfiguration Configuration { get; } - + public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); diff --git a/samples/multi-project/worker/Program.cs b/samples/multi-project/worker/Program.cs index 0fe1b044..776b471b 100644 --- a/samples/multi-project/worker/Program.cs +++ b/samples/multi-project/worker/Program.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/samples/multi-project/worker/QueueWorker.cs b/samples/multi-project/worker/QueueWorker.cs index 3743416f..cc0ecc18 100644 --- a/samples/multi-project/worker/QueueWorker.cs +++ b/samples/multi-project/worker/QueueWorker.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. @@ -57,7 +57,7 @@ namespace Worker throw; } } - + private async Task ConnectAsync(CancellationToken cancellationToken) { ExceptionDispatchInfo? edi = null; diff --git a/samples/single-project/test-project/Program.cs b/samples/single-project/test-project/Program.cs index ec0f0c48..c34efbfb 100644 --- a/samples/single-project/test-project/Program.cs +++ b/samples/single-project/test-project/Program.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/samples/single-project/test-project/Startup.cs b/samples/single-project/test-project/Startup.cs index dd82900b..3a77590f 100644 --- a/samples/single-project/test-project/Startup.cs +++ b/samples/single-project/test-project/Startup.cs @@ -1,4 +1,4 @@ -// Licensed to the .NET Foundation under one or more agreements. +// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. diff --git a/test/E2ETest/TyeRunTests.cs b/test/E2ETest/TyeRunTests.cs index f31956a3..540d9baa 100644 --- a/test/E2ETest/TyeRunTests.cs +++ b/test/E2ETest/TyeRunTests.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; @@ -28,7 +29,7 @@ namespace E2ETest } [Fact] - public async Task SingleProjectTest() + public async Task SingleProjectRunTest() { var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "single-project", "test-project")); using var tempDirectory = TempDirectory.Create(); @@ -96,5 +97,87 @@ namespace E2ETest await host.StopAsync(); } } + + [Fact] + public async Task FrontendBackendRunTest() + { + var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", "frontend-backend")); + using var tempDirectory = TempDirectory.Create(); + DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath); + + var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml")); + + var application = ConfigFactory.FromFile(projectFile); + using var host = new TyeHost(application.ToHostingApplication(), Array.Empty()) + { + Sink = sink, + }; + + await host.StartAsync(); + try + { + var handler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = (a, b, c, d) => true, + AllowAutoRedirect = false + }; + + var client = new HttpClient(new RetryHandler(handler)); + + var dashboardUri = new Uri(host.DashboardWebApplication!.Addresses.First()); + var dashboardResponse = await client.GetStringAsync(dashboardUri); + + await CheckServiceIsUp(application, client, "backend", dashboardUri); + await CheckServiceIsUp(application, client, "frontend", dashboardUri); + } + finally + { + await host.StopAsync(); + } + } + + private async Task CheckServiceIsUp(ConfigApplication application, HttpClient client, string serviceName, Uri dashboardUri) + { + // make sure backend is up before frontend + var service = application.Services.Where(a => a.Name == serviceName).First(); + var binding = service.Bindings.First(); + + var protocol = binding.Protocol != null && binding.Protocol.Length != 0 ? binding.Protocol : "http"; + var hostName = binding.Host != null && binding.Host.Length != 0 ? binding.Host : "localhost"; + + var uriString = $"{protocol}://{hostName}:{binding.Port}"; + + // Confirm that the uri is in the dashboard response. + + var uriBackendProcess = new Uri(uriString); + + // This isn't reliable right now because micronetes only guarantees the process starts, not that + // that kestrel started. + try + { + var appResponse = await client.GetAsync(uriBackendProcess); + Assert.Equal(HttpStatusCode.OK, appResponse.StatusCode); + var content = await appResponse.Content.ReadAsStringAsync(); + if (serviceName == "frontend") + { + Assert.Matches("Frontend Listening IP: (.+)\n", content); + Assert.Matches("Backend Listening IP: (.+)\n", content); + } + } + finally + { + // If we failed, there's a good chance the service isn't running. Let's get the logs either way and put + // them in the output. + foreach (var s in application.Services) + { + var request = new HttpRequestMessage(HttpMethod.Get, new Uri(dashboardUri, $"/api/v1/logs/{s.Name}")); + var response = await client.SendAsync(request); + var text = await response.Content.ReadAsStringAsync(); + + output.WriteLine($"Logs for service: {s.Name}"); + output.WriteLine(text); + } + } + } } }