Skip to content

Commit bc9ca80

Browse files
hhvrcCopilot
andauthored
Create seeder for e2e testing (#205)
* Create seeder * Implement seeders * Fix some issues * Use GUIDv7 * Improve UserSeeder * Make ShockerModelTypes entried fetch oly run once * Don't run app on completion * Implemet rest of the seeders * Comment on db type improvements * Improve enum faking * Improve SafetySettings faking * Code cleanup * Add logging to seeders * more fixing * Better user generation * Update SeedE2E/Seeders/DeviceOtaUpdateSeeder.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent c158de4 commit bc9ca80

33 files changed

+1037
-46
lines changed

API/Program.cs

Lines changed: 4 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using Microsoft.AspNetCore.Http.Connections;
2-
using Microsoft.EntityFrameworkCore;
32
using Microsoft.Extensions.Options;
43
using OpenShock.API.Realtime;
54
using OpenShock.API.Services;
@@ -9,7 +8,6 @@
98
using OpenShock.Common.Extensions;
109
using OpenShock.Common.Hubs;
1110
using OpenShock.Common.JsonSerialization;
12-
using OpenShock.Common.OpenShockDb;
1311
using OpenShock.Common.Options;
1412
using OpenShock.Common.Services.Device;
1513
using OpenShock.Common.Services.LCGNodeProvisioner;
@@ -32,7 +30,9 @@
3230

3331
#endregion
3432

35-
builder.Services.AddOpenShockServices(databaseConfig, redisConfig);
33+
builder.Services.AddOpenShockMemDB(redisConfig);
34+
builder.Services.AddOpenShockDB(databaseConfig);
35+
builder.Services.AddOpenShockServices();
3636

3737
builder.Services.AddSignalR()
3838
.AddOpenShockStackExchangeRedis(options => { options.Configuration = redisConfig; })
@@ -63,25 +63,7 @@
6363

6464
if (!databaseConfig.SkipMigration)
6565
{
66-
Log.Information("Running database migrations...");
67-
using var scope = app.Services.CreateScope();
68-
69-
await using var migrationContext = new MigrationOpenShockContext(
70-
databaseConfig.Conn,
71-
databaseConfig.Debug,
72-
scope.ServiceProvider.GetRequiredService<ILoggerFactory>());
73-
var pendingMigrations = migrationContext.Database.GetPendingMigrations().ToArray();
74-
75-
if (pendingMigrations.Length > 0)
76-
{
77-
Log.Information("Found pending migrations, applying [{@Migrations}]", pendingMigrations);
78-
migrationContext.Database.Migrate();
79-
Log.Information("Applied database migrations... proceeding with startup");
80-
}
81-
else
82-
{
83-
Log.Information("No pending migrations found, proceeding with startup");
84-
}
66+
await app.ApplyPendingOpenShockMigrations(databaseConfig);
8567
}
8668
else
8769
{

Common/OpenShockDb/DiscordWebhook.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public sealed class DiscordWebhook
66

77
public required string Name { get; set; }
88

9-
public required long WebhookId { get; set; }
9+
public required long WebhookId { get; set; } // TODO: This should probably be ulong
1010

1111
public required string WebhookToken { get; set; }
1212

Common/OpenShockDb/PublicShareShocker.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ public sealed class PublicShareShocker : SafetySettings
66

77
public required Guid ShockerId { get; set; }
88

9-
public int? Cooldown { get; set; }
9+
public int? Cooldown { get; set; } // TODO: Should probably be UInt
1010

1111
// Navigations
1212
public PublicShare PublicShare { get; set; } = null!;

Common/OpenShockMiddlewareHelper.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
using Microsoft.AspNetCore.HttpOverrides;
2+
using Microsoft.EntityFrameworkCore;
3+
using Microsoft.Extensions.Logging;
24
using Microsoft.Extensions.Options;
5+
using OpenShock.Common.OpenShockDb;
36
using OpenShock.Common.Options;
47
using OpenShock.Common.Redis;
58
using OpenShock.Common.Utils;
@@ -86,4 +89,30 @@ public static async Task<IApplicationBuilder> UseCommonOpenShockMiddleware(this
8689

8790
return app;
8891
}
92+
93+
public static async Task<IApplicationBuilder> ApplyPendingOpenShockMigrations(this IApplicationBuilder app, DatabaseOptions options)
94+
{
95+
using var scope = app.ApplicationServices.CreateScope();
96+
var loggerFactory = scope.ServiceProvider.GetRequiredService<ILoggerFactory>();
97+
var logger = loggerFactory.CreateLogger("MigrationHelper");
98+
99+
logger.LogInformation("Running database migrations...");
100+
101+
await using var migrationContext = new MigrationOpenShockContext(options.Conn, options.Debug, loggerFactory);
102+
103+
var pendingMigrations = migrationContext.Database.GetPendingMigrations().ToArray();
104+
105+
if (pendingMigrations.Length > 0)
106+
{
107+
logger.LogInformation("Found pending migrations, applying [{@Migrations}]", pendingMigrations);
108+
await migrationContext.Database.MigrateAsync();
109+
logger.LogInformation("Applied database migrations... proceeding with startup");
110+
}
111+
else
112+
{
113+
logger.LogInformation("No pending migrations found, proceeding with startup");
114+
}
115+
116+
return app;
117+
}
89118
}

Common/OpenShockServiceHelper.cs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -69,14 +69,39 @@ public static ConfigurationOptions GetRedisConfigurationOptions(this Configurati
6969
return configurationOptions;
7070
}
7171

72+
public static IServiceCollection AddOpenShockMemDB(this IServiceCollection services, ConfigurationOptions options)
73+
{
74+
// <---- Redis ---->
75+
services.AddSingleton<IConnectionMultiplexer>(ConnectionMultiplexer.Connect(options));
76+
services.AddSingleton<IRedisConnectionProvider, RedisConnectionProvider>();
77+
services.AddSingleton<IRedisPubService, RedisPubService>();
78+
79+
return services;
80+
}
81+
82+
public static IServiceCollection AddOpenShockDB(this IServiceCollection services, DatabaseOptions options)
83+
{
84+
// <---- Postgres EF Core ---->
85+
services.AddDbContextPool<OpenShockContext>(builder => OpenShockContext.ConfigureOptionsBuilder(builder, options.Conn, options.Debug));
86+
services.AddPooledDbContextFactory<OpenShockContext>(builder =>
87+
{
88+
builder.UseNpgsql(options.Conn);
89+
if (options.Debug)
90+
{
91+
builder.EnableSensitiveDataLogging();
92+
builder.EnableDetailedErrors();
93+
}
94+
});
95+
96+
return services;
97+
}
98+
7299
/// <summary>
73100
/// Register all OpenShock services for PRODUCTION use
74101
/// </summary>
75102
/// <param name="services"></param>
76-
/// <param name="databaseOptions"></param>
77-
/// <param name="redisConfigurationOptions"></param>
78103
/// <returns></returns>
79-
public static IServiceCollection AddOpenShockServices(this IServiceCollection services, DatabaseOptions databaseOptions, ConfigurationOptions redisConfigurationOptions)
104+
public static IServiceCollection AddOpenShockServices(this IServiceCollection services)
80105
{
81106
// <---- ASP.NET ---->
82107
services.AddExceptionHandler<OpenShockExceptionHandler>();
@@ -169,23 +194,6 @@ public static IServiceCollection AddOpenShockServices(this IServiceCollection se
169194
.AddAspNetCoreInstrumentation()
170195
.AddHttpClientInstrumentation()
171196
.AddPrometheusExporter());
172-
173-
// <---- Redis ---->
174-
services.AddSingleton<IConnectionMultiplexer>(ConnectionMultiplexer.Connect(redisConfigurationOptions));
175-
services.AddSingleton<IRedisConnectionProvider, RedisConnectionProvider>();
176-
services.AddSingleton<IRedisPubService, RedisPubService>();
177-
178-
// <---- Postgres EF Core ---->
179-
services.AddDbContextPool<OpenShockContext>(builder => OpenShockContext.ConfigureOptionsBuilder(builder, databaseOptions.Conn, databaseOptions.Debug));
180-
services.AddPooledDbContextFactory<OpenShockContext>(builder =>
181-
{
182-
builder.UseNpgsql(databaseOptions.Conn);
183-
if (databaseOptions.Debug)
184-
{
185-
builder.EnableSensitiveDataLogging();
186-
builder.EnableDetailedErrors();
187-
}
188-
});
189197

190198
// <---- OpenShock Services ---->
191199

Cron/Program.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313
var databaseConfig = builder.Configuration.GetDatabaseOptions();
1414
var redisConfig = builder.Configuration.GetRedisConfigurationOptions();
1515

16-
builder.Services.AddOpenShockServices(databaseConfig, redisConfig);
16+
builder.Services.AddOpenShockMemDB(redisConfig);
17+
builder.Services.AddOpenShockDB(databaseConfig);
18+
builder.Services.AddOpenShockServices();
1719

1820
builder.Services.AddHangfire(hangfire =>
1921
hangfire.UsePostgreSqlStorage(c =>

LiveControlGateway/Program.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020
var databaseConfig = builder.Configuration.GetDatabaseOptions();
2121
var redisConfig = builder.Configuration.GetRedisConfigurationOptions();
2222

23-
builder.Services.AddOpenShockServices(databaseConfig, redisConfig);
23+
builder.Services.AddOpenShockMemDB(redisConfig);
24+
builder.Services.AddOpenShockDB(databaseConfig);
25+
builder.Services.AddOpenShockServices();
2426

2527
builder.Services.AddSignalR()
2628
.AddOpenShockStackExchangeRedis(options => { options.Configuration = redisConfig; })

OpenShockBackend.slnx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@
66
<Project Path="LiveControlGateway\LiveControlGateway.csproj" Type="Classic C#" />
77
<Project Path="Cron\Cron.csproj" Type="Classic C#" />
88
<Project Path="MigrationHelper\MigrationHelper.csproj" Type="Classic C#" />
9+
<Project Path="SeedE2E/SeedE2E.csproj" Type="Classic C#" />
910
</Solution>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Bogus.DataSets;
2+
using System.Net;
3+
4+
namespace OpenShock.SeedE2E.Extensions;
5+
6+
public static class BogusInternetExtensions
7+
{
8+
public static IPAddress IpVAnyAddress(this Internet internet, float v6Weight)
9+
{
10+
return internet.Random.Bool(v6Weight) ? internet.Ipv6Address() : internet.IpAddress();
11+
}
12+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using Bogus;
2+
using OpenShock.Common.OpenShockDb;
3+
4+
namespace OpenShock.SeedE2E.Fakers;
5+
6+
public static class FakeSafetySettings
7+
{
8+
public static Faker<T> ApplySafetySettingsRules<T>(this Faker<T> faker) where T : SafetySettings
9+
{
10+
return faker
11+
.RuleFor(m => m.AllowShock, f => f.Random.Bool(0.7f))
12+
.RuleFor(m => m.AllowVibrate, f => f.Random.Bool(0.7f))
13+
.RuleFor(m => m.AllowSound, f => f.Random.Bool(0.7f))
14+
.RuleFor(m => m.AllowLiveControl, f => f.Random.Bool(0.8f))
15+
.RuleFor(m => m.MaxIntensity, f => f.Random.Byte(10, 100))
16+
.RuleFor(m => m.MaxDuration, f => f.Random.UShort(5000, 30000))
17+
.RuleFor(m => m.IsPaused, f => f.Random.Bool(0.1f));
18+
}
19+
}

0 commit comments

Comments
 (0)