diff --git a/docs/reference/schema.md b/docs/reference/schema.md index 4c4856d50..ae4bd999f 100644 --- a/docs/reference/schema.md +++ b/docs/reference/schema.md @@ -85,6 +85,14 @@ Allows configuring the Docker network used for `tye run`. If a network is configured, then all services running in containers will connect to the specified network. Otherwise a Docker network will be created with a generated name, and used to connect all containers. +#### `dashboardPort` (int) + +Allows configuring the dashboard port used for `tye run`. + +If a `--port` is provided via the CLI, it will be used instead. + +If no `--port` argument or `dashboardPort` value is specified, Tye will use the default port (8000), or a random port if the default port is in use. + #### `ingress` (`Ingress[]`) Specifies the list of ingresses. diff --git a/src/Microsoft.Tye.Core/ApplicationBuilder.cs b/src/Microsoft.Tye.Core/ApplicationBuilder.cs index 1a1e2f5c0..5123067c5 100644 --- a/src/Microsoft.Tye.Core/ApplicationBuilder.cs +++ b/src/Microsoft.Tye.Core/ApplicationBuilder.cs @@ -9,17 +9,20 @@ namespace Microsoft.Tye { public sealed class ApplicationBuilder { - public ApplicationBuilder(FileInfo source, string name, ContainerEngine containerEngine) + public ApplicationBuilder(FileInfo source, string name, ContainerEngine containerEngine, int? dashboardPort) { Source = source; Name = name; ContainerEngine = containerEngine; + DashboardPort = dashboardPort; } public FileInfo Source { get; set; } public string Name { get; set; } + public int? DashboardPort { get; set; } + public string? Namespace { get; set; } public ContainerRegistry? Registry { get; set; } diff --git a/src/Microsoft.Tye.Core/ApplicationFactory.cs b/src/Microsoft.Tye.Core/ApplicationFactory.cs index b20aa3eaf..64c700088 100644 --- a/src/Microsoft.Tye.Core/ApplicationFactory.cs +++ b/src/Microsoft.Tye.Core/ApplicationFactory.cs @@ -30,7 +30,7 @@ public static async Task CreateAsync(OutputContext output, F var rootConfig = ConfigFactory.FromFile(source); rootConfig.Validate(); - var root = new ApplicationBuilder(source, rootConfig.Name!, new ContainerEngine(rootConfig.ContainerEngineType)) + var root = new ApplicationBuilder(source, rootConfig.Name!, new ContainerEngine(rootConfig.ContainerEngineType), rootConfig.DashboardPort) { Namespace = rootConfig.Namespace }; diff --git a/src/Microsoft.Tye.Core/ConfigModel/ConfigApplication.cs b/src/Microsoft.Tye.Core/ConfigModel/ConfigApplication.cs index 7093eaa26..b98bd1310 100644 --- a/src/Microsoft.Tye.Core/ConfigModel/ConfigApplication.cs +++ b/src/Microsoft.Tye.Core/ConfigModel/ConfigApplication.cs @@ -24,6 +24,8 @@ public class ConfigApplication public string? Name { get; set; } + public int? DashboardPort { get; set; } + public string? Namespace { get; set; } public string? Registry { get; set; } diff --git a/src/Microsoft.Tye.Core/Serialization/ConfigApplicationParser.cs b/src/Microsoft.Tye.Core/Serialization/ConfigApplicationParser.cs index 7b1f1d5c6..68a1225b7 100644 --- a/src/Microsoft.Tye.Core/Serialization/ConfigApplicationParser.cs +++ b/src/Microsoft.Tye.Core/Serialization/ConfigApplicationParser.cs @@ -45,6 +45,16 @@ public static void HandleConfigApplication(YamlMappingNode yamlMappingNode, Conf throw new TyeYamlException($"Unknown container engine: \"{engine}\""); } break; + case "dashboardPort": + if (int.TryParse(YamlParser.GetScalarValue(key, child.Value), out var dashboardPort)) + { + app.DashboardPort = dashboardPort; + } + else + { + throw new TyeYamlException(child.Key.Start, CoreStrings.FormatMustBeAnInteger(key)); + } + break; case "ingress": YamlParser.ThrowIfNotYamlSequence(key, child.Value); ConfigIngressParser.HandleIngress((child.Value as YamlSequenceNode)!, app.Ingress); diff --git a/src/Microsoft.Tye.Hosting/Model/Application.cs b/src/Microsoft.Tye.Hosting/Model/Application.cs index d88236cf7..2a394a136 100644 --- a/src/Microsoft.Tye.Hosting/Model/Application.cs +++ b/src/Microsoft.Tye.Hosting/Model/Application.cs @@ -12,13 +12,14 @@ namespace Microsoft.Tye.Hosting.Model { public class Application { - public Application(string name, FileInfo source, Dictionary services, ContainerEngine containerEngine) + public Application(string name, FileInfo source, int? dashboardPort, Dictionary services, ContainerEngine containerEngine) { Name = name; Source = source.FullName; ContextDirectory = source.DirectoryName!; Services = services; ContainerEngine = containerEngine; + DashboardPort = dashboardPort; } public string Id { get; } = Guid.NewGuid().ToString(); @@ -31,6 +32,8 @@ public Application(string name, FileInfo source, Dictionary ser public ContainerEngine ContainerEngine { get; set; } + public int? DashboardPort { get; set; } + public Dictionary Services { get; } public Dictionary Items { get; } = new Dictionary(); diff --git a/src/Microsoft.Tye.Hosting/TyeHost.cs b/src/Microsoft.Tye.Hosting/TyeHost.cs index 3a51bee77..b087b526f 100644 --- a/src/Microsoft.Tye.Hosting/TyeHost.cs +++ b/src/Microsoft.Tye.Hosting/TyeHost.cs @@ -155,7 +155,7 @@ private IHost BuildWebApplication(Application application, HostOptions options, }) .ConfigureWebHostDefaults(builder => { - var port = ComputePort(options.Port); + var port = ComputePort(options.Port ?? application.DashboardPort); _computedPort = port; builder.Configure(ConfigureApplication) diff --git a/src/schema/tye-schema.json b/src/schema/tye-schema.json index 90ca4f6d0..2d8685cf8 100644 --- a/src/schema/tye-schema.json +++ b/src/schema/tye-schema.json @@ -26,6 +26,10 @@ "description": "The Docker network to use.", "type": "string" }, + "dashboardPort": { + "description": "Configure the dashboard port used for `tye run`. Can be overridden using the `--port` CLI argument, and falls back to port 8000 if free, or a random port if 8000 is in use.", + "type": "integer" + }, "ingress": { "description": "The application's ingresses.", "type": "array", diff --git a/src/tye/ApplicationBuilderExtensions.cs b/src/tye/ApplicationBuilderExtensions.cs index 1012e669a..c5099c2c1 100644 --- a/src/tye/ApplicationBuilderExtensions.cs +++ b/src/tye/ApplicationBuilderExtensions.cs @@ -213,7 +213,7 @@ public static Application ToHostingApplication(this ApplicationBuilder applicati services.Add(ingress.Name, new Service(description, ServiceSource.Host)); } - return new Application(application.Name, application.Source, services, application.ContainerEngine) { Network = application.Network }; + return new Application(application.Name, application.Source, application.DashboardPort, services, application.ContainerEngine) { Network = application.Network }; } public static Tye.Hosting.Model.EnvironmentVariable ToHostingEnvironmentVariable(this EnvironmentVariableBuilder builder) diff --git a/test/E2ETest/Microsoft.Tye.E2ETests.csproj b/test/E2ETest/Microsoft.Tye.E2ETests.csproj index 71705c10b..08c75665b 100644 --- a/test/E2ETest/Microsoft.Tye.E2ETests.csproj +++ b/test/E2ETest/Microsoft.Tye.E2ETests.csproj @@ -31,6 +31,13 @@ + + + + + + + diff --git a/test/E2ETest/TyeRunTests.cs b/test/E2ETest/TyeRunTests.cs index ee07353a7..03261a909 100644 --- a/test/E2ETest/TyeRunTests.cs +++ b/test/E2ETest/TyeRunTests.cs @@ -1094,6 +1094,93 @@ public async Task RunCliArgDoesNotOverrideYamlMultipleTargetFrameworksTest() }); } + [ConditionalTheory] + [SkipIfDockerNotRunning] + [InlineData("non-standard-dashboard-port", "mcr.microsoft.com/dotnet/core/aspnet:3.1", 8005)] + [InlineData("non-standard-dashboard-port-5.0", "mcr.microsoft.com/dotnet/aspnet:5.0", 8006)] + public async Task RunUsesYamlDashboardPort(string projectName, string baseImage, int expectedDashboardPort) + { + using var projectDirectory = CopyTestProjectDirectory(projectName); + + var projectFile = new FileInfo(Path.Combine(projectDirectory.DirectoryPath, "tye.yaml")); + var outputContext = new OutputContext(_sink, Verbosity.Debug); + var application = await ApplicationFactory.CreateAsync(outputContext, projectFile); + + Assert.Equal(expectedDashboardPort, application.DashboardPort); + + var handler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = (a, b, c, d) => true, + AllowAutoRedirect = false + }; + + var client = new HttpClient(new RetryHandler(handler)); + + await RunHostingApplication(application, new HostOptions() { Docker = true, }, async (app, uri) => + { + // Make sure the dashboard is running on the expected port + Assert.Equal(expectedDashboardPort, uri.Port); + + // Make sure we're running containers + Assert.True(app.Services.All(s => s.Value.Description.RunInfo is DockerRunInfo)); + + // Ensure correct image used + var dockerRunInfo = app.Services.Single().Value.Description.RunInfo as DockerRunInfo; + Assert.Equal(baseImage, dockerRunInfo?.Image); + + // Ensure app runs + var testProjectUri = await GetServiceUrl(client, uri, "test-project"); + var response = await client.GetAsync(testProjectUri); + + Assert.True(response.IsSuccessStatusCode); + }); + } + + [ConditionalTheory] + [SkipIfDockerNotRunning] + [InlineData("non-standard-dashboard-port", "mcr.microsoft.com/dotnet/core/aspnet:3.1", 8005)] + [InlineData("non-standard-dashboard-port-5.0", "mcr.microsoft.com/dotnet/aspnet:5.0", 8006)] + public async Task RunCliPortOverridesYamlDashboardPort(string projectName, string baseImage, int tyeYamlDashboardPort) + { + var cliDashboardPort = 8008; + + using var projectDirectory = CopyTestProjectDirectory(projectName); + + var projectFile = new FileInfo(Path.Combine(projectDirectory.DirectoryPath, "tye.yaml")); + var outputContext = new OutputContext(_sink, Verbosity.Debug); + var application = await ApplicationFactory.CreateAsync(outputContext, projectFile); + + Assert.Equal(tyeYamlDashboardPort, application.DashboardPort); + + var handler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = (a, b, c, d) => true, + AllowAutoRedirect = false + }; + + var client = new HttpClient(new RetryHandler(handler)); + + await RunHostingApplication(application, new HostOptions() { Docker = true, Port = cliDashboardPort }, async (app, uri) => + { + // Make sure the dashboard is running on the expected port passed from the CLI, not the value from tye.yaml + Assert.Equal(cliDashboardPort, uri.Port); + Assert.NotEqual(tyeYamlDashboardPort, uri.Port); + + // Make sure we're running containers + Assert.True(app.Services.All(s => s.Value.Description.RunInfo is DockerRunInfo)); + + // Ensure correct image used + var dockerRunInfo = app.Services.Single().Value.Description.RunInfo as DockerRunInfo; + Assert.Equal(baseImage, dockerRunInfo?.Image); + + // Ensure app runs + var testProjectUri = await GetServiceUrl(client, uri, "test-project"); + var response = await client.GetAsync(testProjectUri); + + Assert.True(response.IsSuccessStatusCode); + }); + } + private async Task GetServiceUrl(HttpClient client, Uri uri, string serviceName) { var serviceResult = await client.GetStringAsync($"{uri}api/v1/services/{serviceName}"); diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/single-project.sln b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/single-project.sln new file mode 100644 index 000000000..b6c03cfbc --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/single-project.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test-project", "test-project\test-project.csproj", "{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x64.ActiveCfg = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x64.Build.0 = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x86.ActiveCfg = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x86.Build.0 = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|Any CPU.Build.0 = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x64.ActiveCfg = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x64.Build.0 = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x86.ActiveCfg = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/Program.cs b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/Program.cs new file mode 100644 index 000000000..3aefed92d --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/Program.cs @@ -0,0 +1,30 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace test_project +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/Startup.cs b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/Startup.cs new file mode 100644 index 000000000..2a2197144 --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/Startup.cs @@ -0,0 +1,44 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace test_project +{ + public class Startup + { + // This method gets called by the runtime. Use this method to add services to the container. + // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + public void ConfigureServices(IServiceCollection services) + { + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/", async context => + { + await context.Response.WriteAsync("Hello World!"); + }); + }); + } + } +} diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/appsettings.Development.json b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/appsettings.Development.json new file mode 100644 index 000000000..8983e0fc1 --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/appsettings.json b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/appsettings.json new file mode 100644 index 000000000..d9d9a9bff --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/test-project.csproj b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/test-project.csproj new file mode 100644 index 000000000..2d4a428ef --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/test-project/test-project.csproj @@ -0,0 +1,8 @@ + + + + netcoreapp5.0 + test_project + + + diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/tye.yaml b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/tye.yaml new file mode 100644 index 000000000..9843a6e3a --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port-5.0/tye.yaml @@ -0,0 +1,7 @@ +# tye application configuration file +# read all about it at https://github.com/dotnet/tye +name: non-standard-dashboard-port +dashboardPort: 8006 +services: +- name: test-project + project: test-project/test-project.csproj diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port/single-project.sln b/test/E2ETest/testassets/projects/non-standard-dashboard-port/single-project.sln new file mode 100644 index 000000000..b6c03cfbc --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port/single-project.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26124.0 +MinimumVisualStudioVersion = 15.0.26124.0 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "test-project", "test-project\test-project.csproj", "{7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x64.ActiveCfg = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x64.Build.0 = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x86.ActiveCfg = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Debug|x86.Build.0 = Debug|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|Any CPU.Build.0 = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x64.ActiveCfg = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x64.Build.0 = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x86.ActiveCfg = Release|Any CPU + {7D3606B2-7B8E-4ABB-BE0A-E0B18285D8F5}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/Program.cs b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/Program.cs new file mode 100644 index 000000000..3aefed92d --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/Program.cs @@ -0,0 +1,30 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace test_project +{ + public class Program + { + public static void Main(string[] args) + { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup(); + }); + } +} diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/Properties/launchSettings.json b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/Properties/launchSettings.json new file mode 100644 index 000000000..990224aca --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:18482", + "sslPort": 44344 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "test_project": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/Startup.cs b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/Startup.cs new file mode 100644 index 000000000..2a2197144 --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/Startup.cs @@ -0,0 +1,44 @@ +// 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. + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace test_project +{ + public class Startup + { + // This method gets called by the runtime. Use this method to add services to the container. + // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + public void ConfigureServices(IServiceCollection services) + { + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + + app.UseRouting(); + + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/", async context => + { + await context.Response.WriteAsync("Hello World!"); + }); + }); + } + } +} diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/appsettings.Development.json b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/appsettings.Development.json new file mode 100644 index 000000000..8983e0fc1 --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/appsettings.json b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/appsettings.json new file mode 100644 index 000000000..d9d9a9bff --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/test-project.csproj b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/test-project.csproj new file mode 100644 index 000000000..86df20c02 --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port/test-project/test-project.csproj @@ -0,0 +1,8 @@ + + + + netcoreapp3.1 + test_project + + + diff --git a/test/E2ETest/testassets/projects/non-standard-dashboard-port/tye.yaml b/test/E2ETest/testassets/projects/non-standard-dashboard-port/tye.yaml new file mode 100644 index 000000000..5cc1514db --- /dev/null +++ b/test/E2ETest/testassets/projects/non-standard-dashboard-port/tye.yaml @@ -0,0 +1,7 @@ +# tye application configuration file +# read all about it at https://github.com/dotnet/tye +name: non-standard-dashboard-port +dashboardPort: 8005 +services: +- name: test-project + project: test-project/test-project.csproj diff --git a/test/Test.Infrastructure/TestHelpers.cs b/test/Test.Infrastructure/TestHelpers.cs index bf4d3e5d7..1f906210c 100644 --- a/test/Test.Infrastructure/TestHelpers.cs +++ b/test/Test.Infrastructure/TestHelpers.cs @@ -251,8 +251,8 @@ static async Task Purge(TyeHost host) var processRunner = new ProcessRunner(logger, replicaRegistry, new ProcessRunnerOptions()); var dockerRunner = new DockerRunner(logger, replicaRegistry); - await processRunner.StartAsync(new Application(host.Application.Name, new FileInfo(host.Application.Source), new Dictionary(), ContainerEngine.Default)); - await dockerRunner.StartAsync(new Application(host.Application.Name, new FileInfo(host.Application.Source), new Dictionary(), ContainerEngine.Default)); + await processRunner.StartAsync(new Application(host.Application.Name, new FileInfo(host.Application.Source), null, new Dictionary(), ContainerEngine.Default)); + await dockerRunner.StartAsync(new Application(host.Application.Name, new FileInfo(host.Application.Source), null, new Dictionary(), ContainerEngine.Default)); } await DoOperationAndWaitForReplicasToChangeState(host, ReplicaState.Stopped, replicas.Length, replicas.ToHashSet(), new HashSet(), TimeSpan.Zero, Purge);