Migrate catalog functional tests
This commit is contained in:
parent
2e0dadf846
commit
cb942598c8
@ -0,0 +1,80 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Polly;
|
||||
using System.Data.SqlClient;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace Catalog.API.Extensions
|
||||
{
|
||||
public static class WebHostExtensions
|
||||
{
|
||||
public static bool IsInKubernetes(this IWebHost host)
|
||||
{
|
||||
var cfg = host.Services.GetService<IConfiguration>();
|
||||
var orchestratorType = cfg.GetValue<string>("OrchestratorType");
|
||||
return orchestratorType?.ToUpper() == "K8S";
|
||||
}
|
||||
|
||||
public static IWebHost MigrateDbContext<TContext>(this IWebHost host, Action<TContext, IServiceProvider> seeder) where TContext : DbContext
|
||||
{
|
||||
var underK8s = host.IsInKubernetes();
|
||||
|
||||
using (var scope = host.Services.CreateScope())
|
||||
{
|
||||
var services = scope.ServiceProvider;
|
||||
|
||||
var logger = services.GetRequiredService<ILogger<TContext>>();
|
||||
|
||||
var context = services.GetService<TContext>();
|
||||
|
||||
try
|
||||
{
|
||||
logger.LogInformation("Migrating database associated with context {DbContextName}", typeof(TContext).Name);
|
||||
|
||||
if (underK8s)
|
||||
{
|
||||
InvokeSeeder(seeder, context, services);
|
||||
}
|
||||
else
|
||||
{
|
||||
var retry = Policy.Handle<SqlException>()
|
||||
.WaitAndRetry(new TimeSpan[]
|
||||
{
|
||||
TimeSpan.FromSeconds(3),
|
||||
TimeSpan.FromSeconds(5),
|
||||
TimeSpan.FromSeconds(8),
|
||||
});
|
||||
|
||||
//if the sql server container is not created on run docker compose this
|
||||
//migration can't fail for network related exception. The retry options for DbContext only
|
||||
//apply to transient exceptions
|
||||
// Note that this is NOT applied when running some orchestrators (let the orchestrator to recreate the failing service)
|
||||
retry.Execute(() => InvokeSeeder(seeder, context, services));
|
||||
}
|
||||
|
||||
logger.LogInformation("Migrated database associated with context {DbContextName}", typeof(TContext).Name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.LogError(ex, "An error occurred while migrating the database used on context {DbContextName}", typeof(TContext).Name);
|
||||
if (underK8s)
|
||||
{
|
||||
throw; // Rethrow under k8s because we rely on k8s to re-run the pod
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
private static void InvokeSeeder<TContext>(Action<TContext, IServiceProvider> seeder, TContext context, IServiceProvider services)
|
||||
where TContext : DbContext
|
||||
{
|
||||
context.Database.Migrate();
|
||||
seeder(context, services);
|
||||
}
|
||||
}
|
||||
}
|
@ -68,7 +68,6 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
|
||||
private static IHostBuilder CreateHostBuilder(IConfiguration configuration, string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureServices(services => services.AddAutofac())
|
||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
||||
.ConfigureWebHostDefaults(builder =>
|
||||
{
|
||||
builder.CaptureStartupErrors(false)
|
||||
|
@ -44,7 +44,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
public IServiceProvider ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddAppInsight(Configuration)
|
||||
.AddGrpc().Services
|
||||
@ -59,6 +59,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
|
||||
var container = new ContainerBuilder();
|
||||
container.Populate(services);
|
||||
|
||||
return new AutofacServiceProvider(container.Build());
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
|
||||
|
@ -33,7 +33,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="$(Microsoft_AspNetCore_Mvc_Testing)" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(Microsoft_NET_Test_Sdk)" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(Microsoft_AspNetCore_TestHost)" />
|
||||
<PackageReference Include="xunit" Version="$(xunit)" />
|
||||
|
@ -1,3 +1,5 @@
|
||||
using Autofac.Extensions.DependencyInjection;
|
||||
using Catalog.API.Extensions;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.TestHost;
|
||||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
||||
@ -5,6 +7,7 @@ using Microsoft.eShopOnContainers.Services.Catalog.API;
|
||||
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.IO;
|
||||
@ -25,14 +28,16 @@ namespace Catalog.FunctionalTests
|
||||
{
|
||||
cb.AddJsonFile("appsettings.json", optional: false)
|
||||
.AddEnvironmentVariables();
|
||||
}).UseStartup<Startup>();
|
||||
})
|
||||
.UseStartup<Startup>();
|
||||
|
||||
|
||||
var testServer = new TestServer(hostBuilder);
|
||||
|
||||
testServer.Host
|
||||
.MigrateDbContext<CatalogContext>((context, services) =>
|
||||
{
|
||||
var env = services.GetService<IHostingEnvironment>();
|
||||
var env = services.GetService<IWebHostEnvironment>();
|
||||
var settings = services.GetService<IOptions<CatalogSettings>>();
|
||||
var logger = services.GetService<ILogger<CatalogContextSeed>>();
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user