using Microsoft.Data.SqlClient; namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.TestSupport.Probes; /// /// Verifies the Galaxy Repository SQL side: SQL Server reachable, ZB database /// present, and at least one deployed object exists (so live tests have something to read). /// Reuses the Windows-auth connection string the repo code defaults to. /// public static class SqlProbe { public const string DefaultConnectionString = "Server=localhost;Database=ZB;Integrated Security=True;TrustServerCertificate=True;Encrypt=False;Connect Timeout=3;"; public static async Task CheckZbDatabaseAsync( string? connectionString = null, CancellationToken ct = default) { connectionString ??= DefaultConnectionString; try { using var conn = new SqlConnection(connectionString); await conn.OpenAsync(ct); // DB_ID returns null when the database doesn't exist on the connected server — distinct // failure mode from "server unreachable", deserves a distinct message. using var cmd = conn.CreateCommand(); cmd.CommandText = "SELECT DB_ID('ZB')"; var dbIdObj = await cmd.ExecuteScalarAsync(ct); if (dbIdObj is null || dbIdObj is DBNull) { return new PrerequisiteCheck("sql:ZB", PrerequisiteCategory.GalaxyRepository, PrerequisiteStatus.Fail, "SQL Server reachable but database ZB does not exist. " + "Create the Galaxy from the IDE or restore a .cab backup."); } return new PrerequisiteCheck("sql:ZB", PrerequisiteCategory.GalaxyRepository, PrerequisiteStatus.Pass, "Connected; ZB database exists."); } catch (SqlException ex) { return new PrerequisiteCheck("sql:ZB", PrerequisiteCategory.GalaxyRepository, PrerequisiteStatus.Fail, $"SQL Server unreachable: {ex.Message}. Ensure MSSQLSERVER service is running (sc.exe start MSSQLSERVER) and TCP 1433 is open."); } catch (Exception ex) { return new PrerequisiteCheck("sql:ZB", PrerequisiteCategory.GalaxyRepository, PrerequisiteStatus.Fail, $"Unexpected probe error: {ex.GetType().Name}: {ex.Message}"); } } /// /// Returns the count of deployed Galaxy objects (deployed_version > 0). Zero /// isn't a hard failure — lets someone boot a fresh Galaxy and still get meaningful /// test-suite output — but it IS a warning because any live-read smoke will have /// nothing to read. /// public static async Task CheckDeployedObjectCountAsync( string? connectionString = null, CancellationToken ct = default) { connectionString ??= DefaultConnectionString; try { using var conn = new SqlConnection(connectionString); await conn.OpenAsync(ct); using var cmd = conn.CreateCommand(); cmd.CommandText = "SELECT COUNT(*) FROM gobject WHERE deployed_version > 0"; var countObj = await cmd.ExecuteScalarAsync(ct); var count = countObj is int i ? i : 0; return count > 0 ? new PrerequisiteCheck("sql:ZB.deployedObjects", PrerequisiteCategory.GalaxyRepository, PrerequisiteStatus.Pass, $"{count} objects deployed — live reads have data to return.") : new PrerequisiteCheck("sql:ZB.deployedObjects", PrerequisiteCategory.GalaxyRepository, PrerequisiteStatus.Warn, "ZB contains no deployed objects. Discovery smoke tests will return empty hierarchies; " + "deploy at least a Platform + AppEngine from the IDE to exercise the read path."); } catch (Exception ex) { return new PrerequisiteCheck("sql:ZB.deployedObjects", PrerequisiteCategory.GalaxyRepository, PrerequisiteStatus.Warn, $"Couldn't count deployed objects: {ex.GetType().Name}: {ex.Message}"); } } }