using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using SQLInsight.Core.Data;
using SQLInsight.Core.Instances;
using SQLInsight.Repository;
namespace SQLInsight.IntegrationTests;
/// The configuration page and its change log, from stored snapshots.
[Collection(SqlServerTestGroup.Name)]
[Trait("Category", "Integration")]
public class ConfigurationPageTests(SqlServerFixture sql) : IAsyncLifetime
{
private readonly string _database = "SQLInsightConfig_" + Guid.NewGuid().ToString("N")[..8];
private InsightRepository _repository = null!;
private int _instanceId;
public async Task InitializeAsync()
{
await sql.ExecuteAsSaAsync($"CREATE DATABASE [{_database}];");
_repository = new InsightRepository(sql.DatabaseConnectionString(_database));
await _repository.MigrateAsync();
var info = new InstanceInfo
{
ServerName = "AX01",
Version = SqlServerVersion.Parse("16.0.4135.4"),
ProductLevel = "RTM",
Edition = "Standard Edition",
EngineEdition = EngineEdition.Standard,
};
_instanceId = await _repository.UpsertInstanceAsync(@"AX01\AX30", info, "SqlClient", false, DateTimeOffset.UtcNow);
}
public async Task DisposeAsync() =>
await sql.ExecuteAsSaAsync($"ALTER DATABASE [{_database}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{_database}];");
[Fact]
public async Task Page_shows_the_setup_non_default_options_and_the_change_log()
{
var now = DateTimeOffset.UtcNow;
await _repository.SaveCollectedAsync(_instanceId, "configuration", new ConfigurationSnapshot
{
CapturedAt = now,
Options = [new ConfigurationOption("max degree of parallelism", 1, 1), new ConfigurationOption("cost threshold for parallelism", 5, 5)],
});
await _repository.SaveCollectedAsync(_instanceId, "instance-config", new InstanceConfigurationSnapshot
{
CapturedAt = now,
Collation = "Danish_Norwegian_CI_AS",
ServicesAvailable = true,
Services = [new ServiceInfo("SQL Server (AX30)", @"KUNDE\svc-ax30", "Automatic", "Running", true)],
InstantFileInitialization = true,
MemoryModel = "LOCK_PAGES",
TempdbFiles = [new TempdbFile("tempdev", "ROWS", 1024, "64 MB", "ubegrænset")],
Changes = [new ConfigurationChange(ConfigurationFingerprint.SpConfigure, "max degree of parallelism", "0", "1", now)],
});
var changes = await _repository.GetConfigurationChangesAsync(_instanceId, now.AddDays(-1), now.AddMinutes(1));
await using var factory = new WebApplicationFactory().WithWebHostBuilder(b =>
{
b.UseEnvironment("Development");
b.UseSetting("SQLInsight:Repository:ConnectionString", sql.DatabaseConnectionString(_database));
b.UseSetting("SQLInsight:Web:Authentication", "None");
});
var name = Uri.EscapeDataString(@"AX01\AX30");
var html = await factory.CreateClient().GetStringAsync($"/instanser/{name}/konfiguration");
var instancePage = await factory.CreateClient().GetStringAsync($"/instanser/{name}");
var change = Assert.Single(changes);
Assert.Equal(("0", "1"), (change.OldValue, change.NewValue));
Assert.Contains("Danish_Norwegian_CI_AS", html, StringComparison.Ordinal);
Assert.Contains(@"KUNDE\svc-ax30", html, StringComparison.Ordinal);
Assert.Contains("Lock Pages in Memory", html, StringComparison.Ordinal);
Assert.Contains("Ændringslog", html, StringComparison.Ordinal);
Assert.Contains("max degree of parallelism", html, StringComparison.Ordinal); // non-default (1 vs 0) and in the log
Assert.DoesNotContain("cost threshold for parallelism", html, StringComparison.Ordinal); // default: not listed
Assert.Contains($"/instanser/{name}/konfiguration", instancePage, StringComparison.Ordinal);
}
}