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) =>
|
private static IHostBuilder CreateHostBuilder(IConfiguration configuration, string[] args) =>
|
||||||
Host.CreateDefaultBuilder(args)
|
Host.CreateDefaultBuilder(args)
|
||||||
.ConfigureServices(services => services.AddAutofac())
|
.ConfigureServices(services => services.AddAutofac())
|
||||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
|
|
||||||
.ConfigureWebHostDefaults(builder =>
|
.ConfigureWebHostDefaults(builder =>
|
||||||
{
|
{
|
||||||
builder.CaptureStartupErrors(false)
|
builder.CaptureStartupErrors(false)
|
||||||
|
@ -44,7 +44,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
|
|||||||
|
|
||||||
public IConfiguration Configuration { get; }
|
public IConfiguration Configuration { get; }
|
||||||
|
|
||||||
public void ConfigureServices(IServiceCollection services)
|
public IServiceProvider ConfigureServices(IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddAppInsight(Configuration)
|
services.AddAppInsight(Configuration)
|
||||||
.AddGrpc().Services
|
.AddGrpc().Services
|
||||||
@ -59,6 +59,7 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API
|
|||||||
var container = new ContainerBuilder();
|
var container = new ContainerBuilder();
|
||||||
container.Populate(services);
|
container.Populate(services);
|
||||||
|
|
||||||
|
return new AutofacServiceProvider(container.Build());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
|
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerFactory loggerFactory)
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<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.NET.Test.Sdk" Version="$(Microsoft_NET_Test_Sdk)" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(Microsoft_AspNetCore_TestHost)" />
|
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="$(Microsoft_AspNetCore_TestHost)" />
|
||||||
<PackageReference Include="xunit" Version="$(xunit)" />
|
<PackageReference Include="xunit" Version="$(xunit)" />
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
using Autofac.Extensions.DependencyInjection;
|
||||||
|
using Catalog.API.Extensions;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.AspNetCore.TestHost;
|
using Microsoft.AspNetCore.TestHost;
|
||||||
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF;
|
||||||
@ -5,6 +7,7 @@ using Microsoft.eShopOnContainers.Services.Catalog.API;
|
|||||||
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
using Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -25,14 +28,16 @@ namespace Catalog.FunctionalTests
|
|||||||
{
|
{
|
||||||
cb.AddJsonFile("appsettings.json", optional: false)
|
cb.AddJsonFile("appsettings.json", optional: false)
|
||||||
.AddEnvironmentVariables();
|
.AddEnvironmentVariables();
|
||||||
}).UseStartup<Startup>();
|
})
|
||||||
|
.UseStartup<Startup>();
|
||||||
|
|
||||||
|
|
||||||
var testServer = new TestServer(hostBuilder);
|
var testServer = new TestServer(hostBuilder);
|
||||||
|
|
||||||
testServer.Host
|
testServer.Host
|
||||||
.MigrateDbContext<CatalogContext>((context, services) =>
|
.MigrateDbContext<CatalogContext>((context, services) =>
|
||||||
{
|
{
|
||||||
var env = services.GetService<IHostingEnvironment>();
|
var env = services.GetService<IWebHostEnvironment>();
|
||||||
var settings = services.GetService<IOptions<CatalogSettings>>();
|
var settings = services.GetService<IOptions<CatalogSettings>>();
|
||||||
var logger = services.GetService<ILogger<CatalogContextSeed>>();
|
var logger = services.GetService<ILogger<CatalogContextSeed>>();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user