- new collector instance-config: collation, edition, version, services and
accounts (sys.dm_server_services, 2008 R2 SP1+), Instant File
Initialization and Lock Pages in Memory (where the build has the
columns), tempdb files, default paths; plus a fingerprint of the whole
setup (sp_configure, trace flags, services, version, tempdb files)
- changes are computed against the previous collection, which the agent
restores from the repository after a restart; migration 0008 keeps them
in insight.ConfigurationChanges (as long as resolved findings)
- SQLI-CFG-013 "Konfiguration ændret": information for a day when
sp_configure, a trace flag or a service account changes (account names
are sensitive evidence)
- page /instanser/{navn}/konfiguration: instance, CPU and memory, services,
tempdb, trace flags, non-default sp_configure (default vs. in use vs.
configured) and the change log; linked from the instance page
- the management report lists configuration changes in the period
- trace flag reading shared by trace-flags and instance-config
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
69 lines
3.4 KiB
C#
69 lines
3.4 KiB
C#
using SQLInsight.Core.Data;
|
|
|
|
namespace SQLInsight.Core.Tests;
|
|
|
|
public class ConfigurationFingerprintTests
|
|
{
|
|
private static readonly DateTimeOffset At = new(2026, 10, 2, 8, 0, 0, TimeSpan.Zero);
|
|
|
|
[Fact]
|
|
public void Changed_added_and_removed_items_are_listed()
|
|
{
|
|
ConfigurationItem[] before =
|
|
[
|
|
new("sp_configure", "max degree of parallelism", "0"),
|
|
new("Trace flag", "1222", "til"),
|
|
new("Tjenestekonto", "SQL Server (MSSQLSERVER)", @"NT Service\MSSQLSERVER"),
|
|
];
|
|
ConfigurationItem[] after =
|
|
[
|
|
new("sp_configure", "max degree of parallelism", "1"),
|
|
new("Trace flag", "3226", "til"),
|
|
new("Tjenestekonto", "SQL Server (MSSQLSERVER)", @"NT Service\MSSQLSERVER"),
|
|
];
|
|
|
|
var changes = ConfigurationFingerprint.Diff(before, after, At);
|
|
|
|
Assert.Equal(3, changes.Count);
|
|
Assert.Contains(new ConfigurationChange("sp_configure", "max degree of parallelism", "0", "1", At), changes);
|
|
Assert.Contains(new ConfigurationChange("Trace flag", "3226", null, "til", At), changes);
|
|
Assert.Contains(new ConfigurationChange("Trace flag", "1222", "til", null, At), changes);
|
|
}
|
|
|
|
[Fact]
|
|
public void Same_setup_has_no_changes() =>
|
|
Assert.Empty(ConfigurationFingerprint.Diff([new("Instans", "Collation", "Danish_Norwegian_CI_AS")], [new("Instans", "Collation", "Danish_Norwegian_CI_AS")], At));
|
|
|
|
[Fact]
|
|
public void Fingerprint_covers_options_flags_services_and_instance_settings()
|
|
{
|
|
var instance = new InstanceConfigurationSnapshot
|
|
{
|
|
CapturedAt = At,
|
|
ProductVersion = "16.0.4135.4",
|
|
ProductLevel = "RTM",
|
|
Collation = "Danish_Norwegian_CI_AS",
|
|
Services = [new ServiceInfo("SQL Server (MSSQLSERVER)", @"KUNDE\svc-sql", "Automatic", "Running", true)],
|
|
InstantFileInitialization = true,
|
|
TempdbFiles = [new TempdbFile("tempdev", "ROWS", 8, "64 MB", "ubegrænset"), new TempdbFile("temp2", "ROWS", 8, "64 MB", "ubegrænset"), new TempdbFile("templog", "LOG", 8, "64 MB", "ubegrænset")],
|
|
};
|
|
|
|
var items = ConfigurationFingerprint.Items(instance, [new ConfigurationOption("max server memory (MB)", 8192, 8192)], [1222]);
|
|
|
|
Assert.Contains(new ConfigurationItem("sp_configure", "max server memory (MB)", "8192"), items);
|
|
Assert.Contains(new ConfigurationItem("Trace flag", "1222", "til"), items);
|
|
Assert.Contains(new ConfigurationItem("Tjenestekonto", "SQL Server (MSSQLSERVER)", @"KUNDE\svc-sql"), items);
|
|
Assert.Contains(new ConfigurationItem("Instans", "Version", "16.0.4135.4 RTM"), items);
|
|
Assert.Contains(new ConfigurationItem("Tempdb", "Antal datafiler", "2"), items);
|
|
Assert.Contains(new ConfigurationItem("Hukommelse", "Instant File Initialization", "til"), items);
|
|
Assert.DoesNotContain(items, i => i.Name == "Lock Pages in Memory"); // unknown on this build: not part of the fingerprint
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData("cost threshold for parallelism", 5L)]
|
|
[InlineData("max server memory (MB)", 2147483647L)]
|
|
[InlineData("default trace enabled", 1L)]
|
|
[InlineData("an option nobody knows", null)]
|
|
public void Defaults_are_known_for_the_documented_options(string option, long? expected) =>
|
|
Assert.Equal(expected, ConfigurationFingerprint.DefaultValue(option));
|
|
}
|