Browse Source

Feed update master (#973)

pull/983/head
Justin Kotalik 6 years ago
committed by GitHub
parent
commit
f4a220df96
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      NuGet.config
  2. 2
      src/Microsoft.Tye.Core/Microsoft.Tye.Core.csproj
  3. 248
      src/Microsoft.Tye.Hosting/HttpProxyService.cs
  4. 5
      src/Microsoft.Tye.Hosting/Microsoft.Tye.Hosting.csproj
  5. 189
      src/Microsoft.Tye.Hosting/TyeHost.cs
  6. 4
      src/Microsoft.Tye.Proxy/Microsoft.Tye.Proxy.csproj
  7. 4
      test/E2ETest/ReplicaStoppingTests.cs
  8. 4
      test/E2ETest/TyeRunTests.cs
  9. 2
      test/Test.Infrastructure/TestHelpers.cs

4
NuGet.config

@ -4,9 +4,7 @@
<clear /> <clear />
<add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" /> <add key="dotnet-eng" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-eng/nuget/v3/index.json" />
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" /> <add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
<add key="nuget" value="https://api.nuget.org/v3/index.json" /> <add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
<add key="featherhttp" value="https://f.feedz.io/davidfowl/featherhttp/nuget/index.json" />
<add key="bedrockframework" value="https://f.feedz.io/davidfowl/bedrockframework/nuget/index.json" />
</packageSources> </packageSources>
<disabledPackageSources /> <disabledPackageSources />
</configuration> </configuration>

2
src/Microsoft.Tye.Core/Microsoft.Tye.Core.csproj

@ -8,7 +8,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="KubernetesClient" Version="4.0.16" /> <PackageReference Include="KubernetesClient" Version="4.0.10" />
<!-- <!--
The Microsoft.Build.Locator package takes care of dynamically loading these assemblies The Microsoft.Build.Locator package takes care of dynamically loading these assemblies
at runtime. We don't need/want to ship them, just to have them as references. at runtime. We don't need/want to ship them, just to have them as references.

248
src/Microsoft.Tye.Hosting/HttpProxyService.cs

@ -12,11 +12,13 @@ using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Proxy; using Microsoft.AspNetCore.Proxy;
using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Matching; using Microsoft.AspNetCore.Routing.Matching;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Tye.Hosting.Model; using Microsoft.Tye.Hosting.Model;
@ -24,7 +26,7 @@ namespace Microsoft.Tye.Hosting
{ {
public partial class HttpProxyService : IApplicationProcessor public partial class HttpProxyService : IApplicationProcessor
{ {
private List<WebApplication> _webApplications = new List<WebApplication>(); private List<IHost> _webApplications = new List<IHost>();
private readonly ILogger _logger; private readonly ILogger _logger;
private ConcurrentDictionary<int, bool> _readyPorts; private ConcurrentDictionary<int, bool> _readyPorts;
@ -50,126 +52,158 @@ namespace Microsoft.Tye.Hosting
if (service.Description.RunInfo is IngressRunInfo runInfo) if (service.Description.RunInfo is IngressRunInfo runInfo)
{ {
var builder = new WebApplicationBuilder(); var host = Host.CreateDefaultBuilder()
.ConfigureWebHostDefaults(builder =>
builder.Services.AddSingleton<MatcherPolicy, IngressHostMatcherPolicy>();
builder.Logging.AddProvider(new ServiceLoggerProvider(service.Logs));
var addresses = new List<string>();
// Bind to the addresses on this resource
for (int i = 0; i < serviceDescription.Replicas; i++)
{
// Fake replicas since it's all running processes
var replica = service.Description.Name + "_" + Guid.NewGuid().ToString().Substring(0, 10).ToLower();
var status = new IngressStatus(service, replica);
service.Replicas[replica] = status;
var ports = new List<int>();
foreach (var binding in serviceDescription.Bindings)
{
if (binding.Port == null)
{
continue;
}
var port = binding.ReplicaPorts[i];
ports.Add(port);
var url = $"{binding.Protocol}://localhost:{port}";
addresses.Add(url);
}
status.Ports = ports;
service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Added, status));
}
builder.Server.UseUrls(addresses.ToArray());
var webApp = builder.Build();
_webApplications.Add(webApp);
// For each ingress rule, bind to the path and host
foreach (var rule in runInfo.Rules)
{
if (!application.Services.TryGetValue(rule.Service, out var target))
{
continue;
}
_logger.LogInformation("Processing ingress rule: Path:{Path}, Host:{Host}, Service:{Service}", rule.Path, rule.Host, rule.Service);
var targetServiceDescription = target.Description;
RegisterListener(target);
var uris = new List<(int Port, Uri Uri)>();
// HTTP before HTTPS (this might change once we figure out certs...)
var targetBinding = targetServiceDescription.Bindings.FirstOrDefault(b => b.Protocol == "http") ??
targetServiceDescription.Bindings.FirstOrDefault(b => b.Protocol == "https");
if (targetBinding == null)
{ {
_logger.LogInformation("Service {ServiceName} does not have any HTTP or HTTPs bindings", targetServiceDescription.Name); var urls = new List<string>();
continue;
}
// For each of the target service replicas, get the base URL // Bind to the addresses on this resource
// based on the replica port for (int i = 0; i < serviceDescription.Replicas; i++)
for (int i = 0; i < targetServiceDescription.Replicas; i++) {
{ // Fake replicas since it's all running processes
var port = targetBinding.ReplicaPorts[i]; var replica = service.Description.Name + "_" + Guid.NewGuid().ToString().Substring(0, 10).ToLower();
var url = $"{targetBinding.Protocol}://localhost:{port}"; var status = new IngressStatus(service, replica);
uris.Add((port, new Uri(url))); service.Replicas[replica] = status;
}
_logger.LogInformation("Service {ServiceName} is using {Urls}", targetServiceDescription.Name, string.Join(",", uris.Select(u => u.ToString())));
// The only load balancing strategy here is round robin var ports = new List<int>();
long count = 0;
RequestDelegate del = async context =>
{
var next = (int)(Interlocked.Increment(ref count) % uris.Count);
// we find the first `Ready` port foreach (var binding in serviceDescription.Bindings)
for (int i = 0; i < uris.Count; i++)
{
if (_readyPorts.ContainsKey(uris[next].Port))
{ {
break; if (binding.Port == null)
{
continue;
}
var port = binding.ReplicaPorts[i];
ports.Add(port);
var url = $"{binding.Protocol}://localhost:{port}";
urls.Add(url);
} }
next = (int)(Interlocked.Increment(ref count) % uris.Count); status.Ports = ports;
}
// if we've looped through all the port and didn't find a single one that is `Ready`, we return HTTP BadGateway service.ReplicaEvents.OnNext(new ReplicaEvent(ReplicaState.Added, status));
if (!_readyPorts.ContainsKey(uris[next].Port))
{
context.Response.StatusCode = (int)HttpStatusCode.BadGateway;
await context.Response.WriteAsync("Bad gateway");
return;
} }
var uri = new UriBuilder(uris[next].Uri)
builder.ConfigureServices(services =>
{ {
Path = rule.PreservePath ? $"{context.Request.Path}" : (string)context.Request.RouteValues["path"] ?? "/", services.AddSingleton<MatcherPolicy, IngressHostMatcherPolicy>();
Query = context.Request.QueryString.Value services.AddLogging(loggingBuilder =>
}; {
loggingBuilder.AddProvider(new ServiceLoggerProvider(service.Logs));
});
await context.ProxyRequest(invoker, uri.Uri); services.Configure<IServerAddressesFeature>(serverAddresses =>
}; {
var addresses = serverAddresses.Addresses;
if (addresses.IsReadOnly)
{
throw new NotSupportedException("Changing the URL isn't supported.");
}
addresses.Clear();
foreach (var u in urls)
{
addresses.Add(u);
}
});
});
builder.UseUrls(urls.ToArray());
builder.Configure(app =>
{
app.UseRouting();
IEndpointConventionBuilder conventions = app.UseEndpoints(endpointBuilder =>
((IEndpointRouteBuilder)webApp).Map((rule.Path?.TrimEnd('/') ?? "") + "/{**path}", del); {
foreach (var rule in runInfo.Rules)
{
if (!application.Services.TryGetValue(rule.Service, out var target))
{
continue;
}
_logger.LogInformation("Processing ingress rule: Path:{Path}, Host:{Host}, Service:{Service}", rule.Path, rule.Host, rule.Service);
var targetServiceDescription = target.Description;
RegisterListener(target);
var uris = new List<(int Port, Uri Uri)>();
// HTTP before HTTPS (this might change once we figure out certs...)
var targetBinding = targetServiceDescription.Bindings.FirstOrDefault(b => b.Protocol == "http") ??
targetServiceDescription.Bindings.FirstOrDefault(b => b.Protocol == "https");
if (targetBinding == null)
{
_logger.LogInformation("Service {ServiceName} does not have any HTTP or HTTPs bindings", targetServiceDescription.Name);
continue;
}
// For each of the target service replicas, get the base URL
// based on the replica port
for (int i = 0; i < targetServiceDescription.Replicas; i++)
{
var port = targetBinding.ReplicaPorts[i];
var url = $"{targetBinding.Protocol}://localhost:{port}";
uris.Add((port, new Uri(url)));
}
_logger.LogInformation("Service {ServiceName} is using {Urls}", targetServiceDescription.Name, string.Join(",", uris.Select(u => u.ToString())));
// The only load balancing strategy here is round robin
long count = 0;
RequestDelegate del = async context =>
{
var next = (int)(Interlocked.Increment(ref count) % uris.Count);
// we find the first `Ready` port
for (int i = 0; i < uris.Count; i++)
{
if (_readyPorts.ContainsKey(uris[next].Port))
{
break;
}
next = (int)(Interlocked.Increment(ref count) % uris.Count);
}
// if we've looped through all the port and didn't find a single one that is `Ready`, we return HTTP BadGateway
if (!_readyPorts.ContainsKey(uris[next].Port))
{
context.Response.StatusCode = (int)HttpStatusCode.BadGateway;
await context.Response.WriteAsync("Bad gateway");
return;
}
var uri = new UriBuilder(uris[next].Uri)
{
Path = rule.PreservePath ? $"{context.Request.Path}" : (string)context.Request.RouteValues["path"] ?? "/",
Query = context.Request.QueryString.Value
};
await context.ProxyRequest(invoker, uri.Uri);
};
IEndpointConventionBuilder conventions =
endpointBuilder.Map((rule.Path?.TrimEnd('/') ?? "") + "/{**path}", del);
if (rule.Host != null)
{
conventions.WithMetadata(new IngressHostMetadata(rule.Host));
}
conventions.WithDisplayName(rule.Service);
}
});
});
});
var webApp = host.Build();
if (rule.Host != null) _webApplications.Add(webApp);
{
conventions.WithMetadata(new IngressHostMetadata(rule.Host));
}
conventions.WithDisplayName(rule.Service); // For each ingress rule, bind to the path and host
}
await webApp.StartAsync(); await webApp.StartAsync();

5
src/Microsoft.Tye.Hosting/Microsoft.Tye.Hosting.csproj

@ -19,12 +19,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Bedrock.Framework" Version="0.1.38-alpha.gd25d5b37ad" /> <PackageReference Include="Bedrock.Framework" Version="0.1.62-alpha.g8a965bbcba" />
<PackageReference Include="FeatherHttp" Version="0.1.42-alpha.gf06a8747e7" />
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.1.0" /> <PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="3.1.0" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="3.0.0" /> <PackageReference Include="Serilog.Extensions.Hosting" Version="3.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" /> <PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
<PackageReference Include="System.IO.Pipelines" Version="4.7.0" /> <PackageReference Include="System.IO.Pipelines" Version="4.7.2" />
<PackageReference Include="System.Reactive" Version="4.3.2" /> <PackageReference Include="System.Reactive" Version="4.3.2" />
<PackageReference Include="YamlDotNet" Version="8.1.2" /> <PackageReference Include="YamlDotNet" Version="8.1.2" />
</ItemGroup> </ItemGroup>

189
src/Microsoft.Tye.Hosting/TyeHost.cs

@ -5,13 +5,17 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.IO;
using System.Linq; using System.Linq;
using System.Net; using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders; using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
@ -32,6 +36,8 @@ namespace Microsoft.Tye.Hosting
private Microsoft.Extensions.Logging.ILogger? _logger; private Microsoft.Extensions.Logging.ILogger? _logger;
private IHostApplicationLifetime? _lifetime; private IHostApplicationLifetime? _lifetime;
private ICollection<string>? _addresses;
private int _computedPort;
private AggregateApplicationProcessor? _processor; private AggregateApplicationProcessor? _processor;
private readonly Application _application; private readonly Application _application;
@ -46,7 +52,11 @@ namespace Microsoft.Tye.Hosting
public Application Application => _application; public Application Application => _application;
public WebApplication? DashboardWebApplication { get; set; } public IHost? DashboardWebApplication { get; set; }
public ICollection<string>? Addresses => _addresses;
public Extensions.Logging.ILogger? Logger => _logger;
// An additional sink that output will be piped to. Useful for testing. // An additional sink that output will be piped to. Useful for testing.
public ILogEventSink? Sink { get; set; } public ILogEventSink? Sink { get; set; }
@ -71,17 +81,20 @@ namespace Microsoft.Tye.Hosting
} }
} }
public async Task<WebApplication> StartAsync() public async Task<IHost> StartAsync()
{ {
var app = BuildWebApplication(_application, _options, Sink); var app = BuildWebApplication(_application, _options, Sink);
DashboardWebApplication = app; DashboardWebApplication = app;
_logger = app.Logger; _logger = DashboardWebApplication.Services.GetRequiredService<ILogger<TyeHost>>();
_lifetime = app.ApplicationLifetime; _lifetime = app.Services.GetRequiredService<IHostApplicationLifetime>();
_logger.LogInformation("Executing application from {Source}", _application.Source); if (_computedPort != _options.Port && _computedPort != DefaultPort)
{
_logger.LogInformation("Default dashboard port {DefaultPort} has been reserved by the application or is in use, choosing random port.", DefaultPort);
}
ConfigureApplication(app); _logger.LogInformation("Executing application from {Source}", _application.Source);
_replicaRegistry = new ReplicaRegistry(_application.ContextDirectory, _logger); _replicaRegistry = new ReplicaRegistry(_application.ContextDirectory, _logger);
@ -89,7 +102,9 @@ namespace Microsoft.Tye.Hosting
await app.StartAsync(); await app.StartAsync();
_logger.LogInformation("Dashboard running on {Address}", app.Addresses.First()); _addresses = DashboardWebApplication.Services.GetRequiredService<IServer>().Features.Get<IServerAddressesFeature>().Addresses;
_logger.LogInformation("Dashboard running on {Address}", _addresses.First());
try try
{ {
@ -103,88 +118,88 @@ namespace Microsoft.Tye.Hosting
if (_options.Dashboard) if (_options.Dashboard)
{ {
OpenDashboard(app.Addresses.First()); OpenDashboard(_addresses.First());
} }
return app; return app;
} }
private static WebApplication BuildWebApplication(Application application, HostOptions options, ILogEventSink? sink) private IHost BuildWebApplication(Application application, HostOptions options, ILogEventSink? sink)
{ {
var args = new List<string>(); return Host.CreateDefaultBuilder()
if (options.Port.HasValue) .UseSerilog((context, configuration) =>
{
args.Add("--port");
args.Add(options.Port.Value.ToString(CultureInfo.InvariantCulture));
}
var builder = WebApplication.CreateBuilder(args.ToArray());
// Logging for this application
builder.Host.UseSerilog((context, configuration) =>
{
var logLevel = options.LogVerbosity switch
{ {
Verbosity.Quiet => LogEventLevel.Warning, var logLevel = options.LogVerbosity switch
Verbosity.Info => LogEventLevel.Information, {
Verbosity.Debug => LogEventLevel.Verbose, Verbosity.Quiet => LogEventLevel.Warning,
_ => default Verbosity.Info => LogEventLevel.Information,
}; Verbosity.Debug => LogEventLevel.Verbose,
_ => default
configuration };
.MinimumLevel.Is(logLevel)
.Filter.ByExcluding(Matching.FromSource("Microsoft.AspNetCore")) configuration
.Filter.ByExcluding(Matching.FromSource("Microsoft.Extensions")) .MinimumLevel.Is(logLevel)
.Filter.ByExcluding(Matching.FromSource("Microsoft.Hosting")) .Filter.ByExcluding(Matching.FromSource("Microsoft.AspNetCore"))
.Enrich .Filter.ByExcluding(Matching.FromSource("Microsoft.Extensions"))
.FromLogContext() .Filter.ByExcluding(Matching.FromSource("Microsoft.Hosting"))
.WriteTo .Enrich
.Console(); .FromLogContext()
.WriteTo
if (sink is object) .Console();
{
configuration.WriteTo.Sink(sink, logLevel); if (sink is object)
} {
}); configuration.WriteTo.Sink(sink, logLevel);
}
builder.Services.AddRazorPages(o => o.RootDirectory = "/Dashboard/Pages"); })
.ConfigureWebHostDefaults(builder =>
builder.Services.AddServerSideBlazor();
builder.Services.AddOptions<StaticFileOptions>()
.PostConfigure(o =>
{ {
var fileProvider = new ManifestEmbeddedFileProvider(typeof(TyeHost).Assembly, "wwwroot"); var port = ComputePort(options.Port);
_computedPort = port;
// Make sure we don't remove the existing file providers (blazor needs this)
o.FileProvider = new CompositeFileProvider(o.FileProvider, fileProvider);
});
builder.Services.AddCors( builder.Configure(ConfigureApplication)
options => .UseUrls($"http://127.0.0.1:{port}");
builder.ConfigureAppConfiguration((b, c) =>
{
b.HostingEnvironment.ApplicationName = "Microsoft.Tye.Hosting";
});
})
.ConfigureServices(services =>
{ {
options.AddPolicy( services.AddRazorPages(o =>
"default", {
policy => o.RootDirectory = "/Dashboard/Pages";
{ });
policy
.AllowAnyOrigin() services.AddServerSideBlazor();
.AllowAnyHeader() services.AddOptions<StaticFileOptions>()
.AllowAnyMethod(); .PostConfigure(o =>
}); {
}); var fileProvider = new ManifestEmbeddedFileProvider(typeof(TyeHost).Assembly, "wwwroot");
builder.Services.AddSingleton(application); // Make sure we don't remove the existing file providers (blazor needs this)
var app = builder.Build(); o.FileProvider = new CompositeFileProvider(o.FileProvider, fileProvider);
return app; });
services.AddCors(
options =>
{
options.AddPolicy(
"default",
policy =>
{
policy
.AllowAnyOrigin()
.AllowAnyHeader()
.AllowAnyMethod();
});
});
services.AddSingleton(application);
})
.Build();
} }
private void ConfigureApplication(WebApplication app) private void ConfigureApplication(IApplicationBuilder app)
{ {
var port = ComputePort(app);
app.Listen($"http://127.0.0.1:{port}");
app.UseDeveloperExceptionPage(); app.UseDeveloperExceptionPage();
app.UseCors("default"); app.UseCors("default");
@ -195,13 +210,15 @@ namespace Microsoft.Tye.Hosting
var api = new TyeDashboardApi(); var api = new TyeDashboardApi();
api.MapRoutes(app); app.UseEndpoints(endpoints =>
{
app.MapBlazorHub(); api.MapRoutes(endpoints);
app.MapFallbackToPage("/_Host"); endpoints.MapBlazorHub();
endpoints.MapFallbackToPage("/_Host");
});
} }
private int ComputePort(WebApplication app) private int ComputePort(int? port)
{ {
// logic for computing the port: // logic for computing the port:
// - we allow the user to specify the port... if they don't // - we allow the user to specify the port... if they don't
@ -210,17 +227,15 @@ namespace Microsoft.Tye.Hosting
// - we don't want to cause conflicts with any of the users known bindings // - we don't want to cause conflicts with any of the users known bindings
// or something else running. // or something else running.
var port = app.Configuration["port"]; if (port.HasValue)
if (!string.IsNullOrEmpty(port))
{ {
// Port was passed in at the command-line, use it! // Port was passed in at the command-line, use it!
return int.Parse(port, NumberStyles.Number, CultureInfo.InvariantCulture); return port.Value;
} }
if (IsPortInUseByBinding(_application, DefaultPort)) if (IsPortInUseByBinding(_application, DefaultPort))
{ {
// Port has been reserved for the app. // Port has been reserved for the app.
app.Logger.LogInformation("Default dashboard port {DefaultPort} has been reserved by the application, choosing random port.", DefaultPort);
return AutodetectPort; return AutodetectPort;
} }
@ -228,8 +243,8 @@ namespace Microsoft.Tye.Hosting
{ {
return DefaultPort; return DefaultPort;
} }
// Port is in use by something already running. // Port is in use by something already running.
app.Logger.LogInformation("Default dashboard port {DefaultPort} is in use, choosing random port.", DefaultPort);
return AutodetectPort; return AutodetectPort;
} }

4
src/Microsoft.Tye.Proxy/Microsoft.Tye.Proxy.csproj

@ -6,8 +6,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Bedrock.Framework" Version="0.1.38-alpha.gd25d5b37ad" /> <PackageReference Include="Bedrock.Framework" Version="0.1.62-alpha.g8a965bbcba" />
<PackageReference Include="System.IO.Pipelines" Version="4.7.0" /> <PackageReference Include="System.IO.Pipelines" Version="4.7.2" />
</ItemGroup> </ItemGroup>
<!-- Include *.deps.json and *.runtimeconfig.json in ContentWithTargetPath so they will be copied to the output folder of projects <!-- Include *.deps.json and *.runtimeconfig.json in ContentWithTargetPath so they will be copied to the output folder of projects

4
test/E2ETest/ReplicaStoppingTests.cs

@ -112,7 +112,7 @@ namespace E2ETest
{ {
await StartHostAndWaitForReplicasToStart(host); await StartHostAndWaitForReplicasToStart(host);
var uri = new Uri(host.DashboardWebApplication!.Addresses.First()); var uri = new Uri(host.Addresses!.First());
await execute(host, uri!); await execute(host, uri!);
} }
@ -120,7 +120,7 @@ namespace E2ETest
{ {
if (host.DashboardWebApplication != null) if (host.DashboardWebApplication != null)
{ {
var uri = new Uri(host.DashboardWebApplication!.Addresses.First()); var uri = new Uri(host.Addresses!.First());
using var client = new HttpClient(); using var client = new HttpClient();

4
test/E2ETest/TyeRunTests.cs

@ -1105,7 +1105,7 @@ services:
{ {
await StartHostAndWaitForReplicasToStart(host); await StartHostAndWaitForReplicasToStart(host);
var uri = new Uri(host.DashboardWebApplication!.Addresses.First()); var uri = new Uri(host.Addresses!.First());
await execute(host.Application, uri!); await execute(host.Application, uri!);
} }
@ -1113,7 +1113,7 @@ services:
{ {
if (host.DashboardWebApplication != null) if (host.DashboardWebApplication != null)
{ {
var uri = new Uri(host.DashboardWebApplication!.Addresses.First()); var uri = new Uri(host.Addresses!.First());
using var client = new HttpClient(); using var client = new HttpClient();

2
test/Test.Infrastructure/TestHelpers.cs

@ -246,7 +246,7 @@ namespace Test.Infrastructure
{ {
static async Task Purge(TyeHost host) static async Task Purge(TyeHost host)
{ {
var logger = host.DashboardWebApplication!.Logger; var logger = host.Logger;
var replicaRegistry = new ReplicaRegistry(host.Application.ContextDirectory, logger); var replicaRegistry = new ReplicaRegistry(host.Application.ContextDirectory, logger);
var processRunner = new ProcessRunner(logger, replicaRegistry, new ProcessRunnerOptions()); var processRunner = new ProcessRunner(logger, replicaRegistry, new ProcessRunnerOptions());
var dockerRunner = new DockerRunner(logger, replicaRegistry); var dockerRunner = new DockerRunner(logger, replicaRegistry);

Loading…
Cancel
Save