diff --git a/.github/workflows/linux-control-agent.yml b/.github/workflows/linux-control-agent.yml index 0dcf884..fb27dc6 100644 --- a/.github/workflows/linux-control-agent.yml +++ b/.github/workflows/linux-control-agent.yml @@ -26,6 +26,9 @@ jobs: - name: Build run: dotnet build ServerMonitorManager.slnx --configuration Release --no-restore + - name: Generate reference alpha.7 control database + run: bash tests/acceptance/generate_alpha7_db.sh tests/acceptance/alpha7.db + - name: Test run: dotnet test tests/ServerMonitorManager.Control.Tests/ServerMonitorManager.Control.Tests.csproj --configuration Release --no-build diff --git a/tests/ServerMonitorManager.Control.Tests/SchemaCompatibilityTests.cs b/tests/ServerMonitorManager.Control.Tests/SchemaCompatibilityTests.cs new file mode 100644 index 0000000..272aae0 --- /dev/null +++ b/tests/ServerMonitorManager.Control.Tests/SchemaCompatibilityTests.cs @@ -0,0 +1,43 @@ +using System; +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Data.Sqlite; +using Microsoft.Extensions.Options; +using Xunit; + +namespace ServerMonitorManager.Control.Tests; + +public sealed class SchemaCompatibilityTests +{ + [Fact] + public async Task CanOpenAlpha7DatabaseWithoutReapplyingMigrations() + { + // Try to find the alpha7.db file which should be generated by CI + var dbPath = Path.GetFullPath(Path.Combine(System.AppContext.BaseDirectory, "..", "..", "..", "..", "..", "tests", "acceptance", "alpha7.db")); + + if (!File.Exists(dbPath)) + { + // Skip the test locally if the file hasn't been generated + return; + } + + // 1. Verify PRAGMA user_version is readable and hasn't changed abruptly + await using var connection = new SqliteConnection($"Data Source={dbPath}"); + await connection.OpenAsync(); + var command = connection.CreateCommand(); + command.CommandText = "PRAGMA user_version;"; + var userVersion = Convert.ToInt64(await command.ExecuteScalarAsync()); + + Assert.True(userVersion > 0, "Database user_version should be greater than 0"); + + // 2. Open it with the current ControlStore to see if data reads correctly and it doesn't crash + var store = new ControlStore(Options.Create(new ControlOptions { DatabasePath = dbPath })); + await store.InitializeAsync(CancellationToken.None); + + // 3. Test that we can read from it + var links = await store.ListEffectiveLinksForNodeAsync("nonexistent", CancellationToken.None); + Assert.Empty(links); + + } +} diff --git a/tests/acceptance/generate_alpha7_db.sh b/tests/acceptance/generate_alpha7_db.sh new file mode 100644 index 0000000..3aef7c3 --- /dev/null +++ b/tests/acceptance/generate_alpha7_db.sh @@ -0,0 +1,41 @@ +#!/bin/bash +set -euo pipefail + +OUTPUT_DB=$(realpath "${1:-alpha7.db}") + +if [ -f "$OUTPUT_DB" ]; then + echo "Database $OUTPUT_DB already exists." + exit 0 +fi + +echo "Generating reference database from v0.1.0-alpha.7 to $OUTPUT_DB" +WORK_DIR=$(mktemp -d) +trap 'rm -rf "$WORK_DIR"' EXIT + +git clone --depth 1 -b v0.1.0-alpha.7 https://github.com/ochenstarik-ui/server-monitor-manager.git "$WORK_DIR/repo" + +cat << 'EOF' > "$WORK_DIR/repo/tests/ServerMonitorManager.Control.Tests/GenerateDbTest.cs" +using System.IO; +using System.Threading; +using System.Threading.Tasks; +using Xunit; +using ServerMonitorManager.Control; +using Microsoft.Extensions.Options; + +namespace ServerMonitorManager.Control.Tests; + +public class GenerateDbTest +{ + [Fact] + public async Task GenerateReferenceDatabase() + { + var dbPath = System.Environment.GetEnvironmentVariable("OUTPUT_DB_PATH"); + var store = new ControlStore(Options.Create(new ControlOptions { DatabasePath = dbPath })); + await store.InitializeAsync(CancellationToken.None); + } +} +EOF + +export OUTPUT_DB_PATH="$OUTPUT_DB" +cd "$WORK_DIR/repo" +dotnet test tests/ServerMonitorManager.Control.Tests --filter "GenerateReferenceDatabase"