diff --git a/CHANGELOG.md b/CHANGELOG.md
index 718e9eb..bd80964 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
# Changelog
+## v5.0.1
+
+### 🐛 Bug Fixes
+
+- Fixed a bug where internal packages were not available at installation. Preventing NotoriousTest from being installed.
+- All internal packages are now available to download from Nuget.org, but every class is internal. Which makes them
+ impossible to use.
+
## v5.0.0
### ✨ Features
diff --git a/Directory.Build.props b/Directory.Build.props
index 513e3ae..739c5f4 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -8,7 +8,7 @@
icon.png
LICENSE.txt
README.md
- 5.0.0
+ 5.0.1
true
high
all
diff --git a/DoggyDog/DoggyDog.csproj b/DoggyDog/DoggyDog.csproj
index 568a89c..94f9b4b 100644
--- a/DoggyDog/DoggyDog.csproj
+++ b/DoggyDog/DoggyDog.csproj
@@ -10,8 +10,8 @@
-
-
+
+
diff --git a/DoggyDog/DoggyDogRecoveryWatchdog.cs b/DoggyDog/DoggyDogRecoveryWatchdog.cs
index 4adf86a..761eb72 100644
--- a/DoggyDog/DoggyDogRecoveryWatchdog.cs
+++ b/DoggyDog/DoggyDogRecoveryWatchdog.cs
@@ -4,7 +4,7 @@
using NotoriousTest.Core;
using NotoriousTest.Core.Infrastructures.Cleaner;
using NotoriousTest.Core.Registry;
-using NotoriousTest.Watchdog;
+using NotoriousTest.Internal.Watchdog;
using System.Diagnostics;
using System.Reflection;
diff --git a/DoggyDog/Program.cs b/DoggyDog/Program.cs
index 1940a72..c910339 100644
--- a/DoggyDog/Program.cs
+++ b/DoggyDog/Program.cs
@@ -4,7 +4,7 @@
using Microsoft.Data.Sqlite;
-using NotoriousTest.SqlLiteRegistry;
+using NotoriousTest.Internal.SqlLiteRegistry;
Logger logger = Logger.Instance;
diff --git a/NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTestFramework.cs b/NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTestFramework.cs
index a95806f..fc71130 100644
--- a/NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTestFramework.cs
+++ b/NotoriousTest.IntegrationTests/DoggyDog/DoggyDogTestFramework.cs
@@ -9,7 +9,7 @@
using NotoriousTest.Core.Logger;
using NotoriousTest.Core.Registry;
using NotoriousTest.Sqlite;
-using NotoriousTest.SqlLiteRegistry;
+using NotoriousTest.Internal.SqlLiteRegistry;
using System.Diagnostics;
using System.Runtime.InteropServices;
diff --git a/NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTestsBase.cs b/NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTestsBase.cs
index 32bcc3e..84a3677 100644
--- a/NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTestsBase.cs
+++ b/NotoriousTest.IntegrationTests/Infrastructure/InfrastructureLifecycleTestsBase.cs
@@ -3,7 +3,7 @@
using NotoriousTest.Core;
using NotoriousTest.Core.Logger;
using NotoriousTest.IntegrationTests.SystemUnderTest;
-using NotoriousTest.SqlLiteRegistry;
+using NotoriousTest.Internal.SqlLiteRegistry;
using NotoriousTest.XUnit;
namespace NotoriousTest.IntegrationTests.Infrastructure;
diff --git a/NotoriousTest.Internal.Runtime/NotoriousTest.Internal.Runtime.csproj b/NotoriousTest.Internal.Runtime/NotoriousTest.Internal.Runtime.csproj
new file mode 100644
index 0000000..11ea6a6
--- /dev/null
+++ b/NotoriousTest.Internal.Runtime/NotoriousTest.Internal.Runtime.csproj
@@ -0,0 +1,18 @@
+
+
+ net8.0
+ NotoriousTest.Internal.Runtime
+ [Internal] Provides the runtime configuration layer for NotoriousTest. Not intended for direct consumption — use the NotoriousTest package instead.
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NotoriousTest.Internal.Runtime/RuntimeConfigurationEntity.cs b/NotoriousTest.Internal.Runtime/RuntimeConfigurationEntity.cs
new file mode 100644
index 0000000..eab5ac6
--- /dev/null
+++ b/NotoriousTest.Internal.Runtime/RuntimeConfigurationEntity.cs
@@ -0,0 +1,11 @@
+namespace NotoriousTest.Internal.Runtime;
+
+internal record RuntimeConfigurationEntity(RuntimeOptions RuntimeOptions);
+
+internal record RuntimeOptions(
+ string Tfm,
+ FrameworkEntry? Framework,
+ FrameworkEntry[]? Frameworks
+);
+
+internal record FrameworkEntry(string Name, string Version);
diff --git a/NotoriousTest.Internal.Runtime/RuntimeConfigurationProvider.cs b/NotoriousTest.Internal.Runtime/RuntimeConfigurationProvider.cs
new file mode 100644
index 0000000..e4b1b03
--- /dev/null
+++ b/NotoriousTest.Internal.Runtime/RuntimeConfigurationProvider.cs
@@ -0,0 +1,88 @@
+using System.Diagnostics;
+using System.Reflection;
+using System.Text.Json;
+using NotoriousTest.Core.Logger;
+using NotoriousTest.Core.Runtime;
+
+namespace NotoriousTest.Internal.Runtime;
+
+internal class RuntimeConfigurationProvider : IRuntime
+{
+ private const string RuntimeFile = "runtimeconfig.json";
+ private readonly ITestLogger _logger;
+
+ private readonly JsonSerializerOptions JSON_OPTIONS = new() { PropertyNameCaseInsensitive = true };
+ private RuntimeConfiguration? _cache;
+
+ public RuntimeConfigurationProvider(ITestLogger logger)
+ {
+ _logger = logger;
+ }
+
+ public RuntimeConfiguration? GetSupportedRuntimes(Assembly executingAssembly)
+ {
+ if (_cache != null) return _cache;
+
+ string assemblyPath = executingAssembly.Location;
+ string runtimePath = Path.ChangeExtension(assemblyPath, RuntimeFile);
+
+ if (!File.Exists(runtimePath))
+ return null;
+
+
+ string json = File.ReadAllText(runtimePath);
+
+
+ RuntimeConfigurationEntity? entity = JsonSerializer.Deserialize(json, JSON_OPTIONS);
+ if (entity == null)
+ return null;
+
+ FrameworkEntry[]? frameworkEntries = entity.RuntimeOptions.Frameworks ?? [entity.RuntimeOptions.Framework!];
+ SupportedFramework[]? frameworks = frameworkEntries.Select(ToDomain).ToArray();
+
+ var result = new RuntimeConfiguration(entity.RuntimeOptions.Tfm, frameworks);
+ _cache = result;
+ return result;
+ }
+
+ private SupportedFramework ToDomain(FrameworkEntry entry) =>
+ new(entry.Name, entry.Version, GetNearestVersionDirectory(entry));
+
+ private string? GetNearestVersionDirectory(FrameworkEntry framework)
+ {
+ string dotnetRoot = GetDotnetRoot();
+
+ string frameworkPath = $"{dotnetRoot}/shared/{framework.Name}";
+
+ string prefix = $"{new Version(framework.Version).Major}.{new Version(framework.Version).Minor}.";
+ // Find the nearest version
+ string? best = Directory.GetDirectories(frameworkPath)
+ .Where(d => Path.GetFileName(d).StartsWith(prefix))
+ .OrderByDescending(d => new Version(Path.GetFileName(d)))
+ .FirstOrDefault();
+
+ return best;
+ }
+
+ private string GetDotnetRoot()
+ {
+ string? dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT");
+
+ if (!string.IsNullOrWhiteSpace(dotnetRoot))
+ return dotnetRoot;
+
+ string mainModule = Process.GetCurrentProcess().MainModule!.FileName;
+
+ // If the test project is self-contained (wich is rare), the main module will be the test executable itself.
+ bool isNotSelfContained = Path.GetFileNameWithoutExtension(mainModule)
+ .Equals("dotnet", StringComparison.OrdinalIgnoreCase);
+
+ if (isNotSelfContained)
+ return Path.GetDirectoryName(mainModule)!;
+
+ return Path.Combine(
+ Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
+ "dotnet"
+ );
+ }
+}
diff --git a/NotoriousTest.Internal.SqlLiteRegistry/InfrastructureRegistryEntryEntity.cs b/NotoriousTest.Internal.SqlLiteRegistry/InfrastructureRegistryEntryEntity.cs
new file mode 100644
index 0000000..dd45349
--- /dev/null
+++ b/NotoriousTest.Internal.SqlLiteRegistry/InfrastructureRegistryEntryEntity.cs
@@ -0,0 +1,55 @@
+using System.Globalization;
+using System.Text.Json;
+using NotoriousTest.Core.Registry;
+
+namespace NotoriousTest.Internal.SqlLiteRegistry;
+
+internal class InfrastructureRegistryEntryEntity
+{
+ public string InfrastructureId { get; set; }
+ public string InfrastructureType { get; set; }
+ public string EnvironmentId { get; set; }
+ public int ProcessID { get; set; }
+ public string? Metadata { get; set; }
+ public string? MetadataType { get; set; }
+ public string? LastResetDate { get; set; }
+ public string CreationDate { get; set; }
+ public string UpdateDate { get; set; }
+
+ internal static InfrastructureRegistryEntryEntity? FromDomain(InfrastuctureRegistryEntry entry) =>
+ new()
+ {
+ InfrastructureId = entry.InfrastructureId.ToString(),
+ InfrastructureType = entry.InfrastructureType.AssemblyQualifiedName,
+ EnvironmentId = entry.EnvironmentId.ToString(),
+ ProcessID = entry.ProcessID,
+ Metadata = JsonSerializer.Serialize(entry.Metadata),
+ MetadataType = entry.Metadata?.GetType().AssemblyQualifiedName,
+ LastResetDate = entry.LastResetDate?.ToString("O")
+ };
+
+ internal InfrastuctureRegistryEntry ToDomain()
+ {
+ Type? metadataType = null;
+
+ if (MetadataType != null) metadataType = Type.GetType(MetadataType);
+
+ var infraType = Type.GetType(InfrastructureType);
+ if (infraType == null) throw new TypeLoadException($"Unable to load type {InfrastructureType}");
+
+ return new InfrastuctureRegistryEntry
+ {
+ InfrastructureId = Guid.Parse(InfrastructureId),
+ InfrastructureType = Type.GetType(InfrastructureType),
+ EnvironmentId = Guid.Parse(EnvironmentId),
+ ProcessID = ProcessID,
+ Metadata = !(Metadata is null) && !(metadataType is null)
+ ? JsonSerializer.Deserialize(Metadata, metadataType)
+ : null,
+ LastResetDate =
+ LastResetDate != null ? DateTime.Parse(LastResetDate, null, DateTimeStyles.RoundtripKind) : null,
+ CreationDate = DateTime.Parse(CreationDate, null, DateTimeStyles.RoundtripKind),
+ UpdateDate = DateTime.Parse(UpdateDate, null, DateTimeStyles.RoundtripKind)
+ };
+ }
+}
diff --git a/NotoriousTest.Internal.SqlLiteRegistry/NotoriousTest.Internal.SqlLiteRegistry.csproj b/NotoriousTest.Internal.SqlLiteRegistry/NotoriousTest.Internal.SqlLiteRegistry.csproj
new file mode 100644
index 0000000..62dbd5a
--- /dev/null
+++ b/NotoriousTest.Internal.SqlLiteRegistry/NotoriousTest.Internal.SqlLiteRegistry.csproj
@@ -0,0 +1,25 @@
+
+
+ net8.0
+ NotoriousTest.Internal.SqlLiteRegistry
+ [Internal] SQLite-backed infrastructure registry for NotoriousTest. Not intended for direct consumption — use the NotoriousTest package instead.
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NotoriousTest.Internal.SqlLiteRegistry/SqliteRegistryProvider.cs b/NotoriousTest.Internal.SqlLiteRegistry/SqliteRegistryProvider.cs
new file mode 100644
index 0000000..10b61fb
--- /dev/null
+++ b/NotoriousTest.Internal.SqlLiteRegistry/SqliteRegistryProvider.cs
@@ -0,0 +1,126 @@
+using System.Data;
+using Dapper;
+using Microsoft.Data.Sqlite;
+using NotoriousTest.Core;
+using NotoriousTest.Core.Registry;
+
+namespace NotoriousTest.Internal.SqlLiteRegistry;
+
+internal partial class SqliteRegistryProvider : IRegistry
+{
+ private readonly SqliteRegistryProviderConfiguration _configuration;
+
+ public SqliteRegistryProvider(SqliteRegistryProviderConfiguration configuration)
+ {
+ _configuration = configuration;
+ }
+
+ private SqliteConnectionStringBuilder ConnectionString => new(_configuration.ConnectionString);
+
+ private SqliteConnection Connection
+ {
+ get
+ {
+ var connection = new SqliteConnection(ConnectionString.ToString());
+
+ if (connection.State != ConnectionState.Open) connection.Open();
+
+ connection.Execute("PRAGMA SYNCHRONOUS=NORMAL;PRAGMA JOURNAL_MODE=WAL;");
+ return connection;
+ }
+ }
+
+ public event Action OnInfrastructureReset;
+ public event Action OnInfrastructureDestroyed;
+ public event Action OnInfrastructureCreated;
+
+
+ public async Task Ensure()
+ {
+ string directory = Path.GetDirectoryName(ConnectionString.DataSource);
+ if (!Directory.Exists(directory)) Directory.CreateDirectory(directory);
+
+ await using SqliteConnection connection = Connection;
+
+ await connection.ExecuteAsync(ENSURE_REGISTRY);
+ }
+
+ public async Task Register(InfrastuctureRegistryEntry entry)
+ {
+ await using SqliteConnection connection = Connection;
+ InfrastructureRegistryEntryEntity entity =
+ await connection.QuerySingleAsync(REGISTER_INFRASTRUCTURE,
+ InfrastructureRegistryEntryEntity.FromDomain(entry));
+
+ return entity.ToDomain();
+ }
+
+ public async Task Remove(Guid id)
+ {
+ await using SqliteConnection connection = Connection;
+
+ int deletedRows =
+ await connection.ExecuteAsync(REMOVE_INFRASTRUCTURE, new { InfrastructureId = id.ToString() });
+ return deletedRows > 0;
+ }
+
+ public async Task NotifyReset(Guid id)
+ {
+ await using SqliteConnection connection = Connection;
+
+ await connection.ExecuteAsync(UPDATE_INFRASTRUCTURE_RESET_DATE, new { InfrastructureId = id.ToString() });
+ }
+
+ public async Task> GetByProcessId(int processId)
+ {
+ await using SqliteConnection connection = Connection;
+
+ IEnumerable entries =
+ await connection.QueryAsync(GET_BY_PROCESS_ID,
+ new { ProcessID = processId });
+ return entries.Select(entry => entry.ToDomain());
+ }
+
+ public async Task> GetByEnvironmentId(EnvironmentId environmentId)
+ {
+ await using SqliteConnection connection = Connection;
+
+ IEnumerable entries =
+ await connection.QueryAsync(GET_BY_ENVIRONMENT_ID,
+ new { EnvironmentId = environmentId.Value.ToString() });
+ return entries.Select(entry => entry.ToDomain());
+ }
+
+ public async Task Watch(EnvironmentId environmentId, CancellationToken ct)
+ {
+ var snapshot = (await GetByEnvironmentId(environmentId)).ToDictionary(x => x.InfrastructureId);
+
+ do
+ {
+ IEnumerable infras = await GetByEnvironmentId(environmentId);
+
+ foreach (InfrastuctureRegistryEntry infra in infras)
+ {
+ if (!snapshot.TryGetValue(infra.InfrastructureId, out InfrastuctureRegistryEntry? previous))
+ OnInfrastructureCreated?.Invoke(infra);
+
+ if (previous is not null && infra.LastResetDate != previous.LastResetDate)
+ OnInfrastructureReset?.Invoke(infra);
+ }
+
+ foreach ((Guid key, InfrastuctureRegistryEntry infrastructure) in snapshot)
+ if (!infras.Any(i => i.InfrastructureId == infrastructure.InfrastructureId))
+ OnInfrastructureDestroyed?.Invoke(infrastructure);
+
+ snapshot = infras.ToDictionary(x => x.InfrastructureId);
+
+ try
+ {
+ await Task.Delay(10, ct);
+ }
+ catch (OperationCanceledException)
+ {
+ }
+ } while (!ct.IsCancellationRequested);
+ }
+}
diff --git a/NotoriousTest.Internal.SqlLiteRegistry/SqliteRegistryProviderConfiguration.cs b/NotoriousTest.Internal.SqlLiteRegistry/SqliteRegistryProviderConfiguration.cs
new file mode 100644
index 0000000..601a00a
--- /dev/null
+++ b/NotoriousTest.Internal.SqlLiteRegistry/SqliteRegistryProviderConfiguration.cs
@@ -0,0 +1,6 @@
+namespace NotoriousTest.Internal.SqlLiteRegistry;
+
+internal class SqliteRegistryProviderConfiguration
+{
+ public string ConnectionString { get; set; }
+}
diff --git a/NotoriousTest.SqlLiteRegistry/SqliteRegistryProviderQueries.cs b/NotoriousTest.Internal.SqlLiteRegistry/SqliteRegistryProviderQueries.cs
similarity index 69%
rename from NotoriousTest.SqlLiteRegistry/SqliteRegistryProviderQueries.cs
rename to NotoriousTest.Internal.SqlLiteRegistry/SqliteRegistryProviderQueries.cs
index 07262c7..2e622a9 100644
--- a/NotoriousTest.SqlLiteRegistry/SqliteRegistryProviderQueries.cs
+++ b/NotoriousTest.Internal.SqlLiteRegistry/SqliteRegistryProviderQueries.cs
@@ -1,9 +1,10 @@
-namespace NotoriousTest.SqlLiteRegistry
+namespace NotoriousTest.Internal.SqlLiteRegistry;
+
+internal partial class SqliteRegistryProvider
{
- internal partial class SqliteRegistryProvider
- {
- protected const string TABLE_NAME = "InfrastructureRegistry";
- protected const string ENSURE_REGISTRY = @$"
+ protected const string TABLE_NAME = "InfrastructureRegistry";
+
+ protected const string ENSURE_REGISTRY = @$"
CREATE TABLE IF NOT EXISTS {TABLE_NAME}(
InfrastructureId TEXT PRIMARY KEY,
InfrastructureType TEXT NOT NULL,
@@ -17,30 +18,29 @@ LastResetDate TEXT
)
";
- protected const string REGISTER_INFRASTRUCTURE = @$"
+ protected const string REGISTER_INFRASTRUCTURE = @$"
INSERT INTO {TABLE_NAME}(InfrastructureId, InfrastructureType, EnvironmentId, ProcessID, Metadata, MetadataType, CreationDate, UpdateDate, LastResetDate)
VALUES(@InfrastructureId, @InfrastructureType, @EnvironmentId, @ProcessID, @Metadata, @MetadataType, datetime('now', 'utc'), datetime('now', 'utc'), null)
RETURNING *
";
- protected const string REMOVE_INFRASTRUCTURE = @$"
+ protected const string REMOVE_INFRASTRUCTURE = @$"
DELETE FROM {TABLE_NAME} WHERE InfrastructureId = @InfrastructureId;
";
- protected const string GET_BY_PROCESS_ID = @$"
+ protected const string GET_BY_PROCESS_ID = @$"
SELECT * FROM {TABLE_NAME} WHERE ProcessID = @ProcessID;
";
- protected const string GET_BY_ENVIRONMENT_ID = @$"
+ protected const string GET_BY_ENVIRONMENT_ID = @$"
SELECT * FROM {TABLE_NAME} WHERE EnvironmentId = @EnvironmentId;
";
- protected const string GET_BY_ROWID = $@"
+ protected const string GET_BY_ROWID = $@"
SELECT * FROM {TABLE_NAME} WHERE rowid = @rowId
";
- protected const string UPDATE_INFRASTRUCTURE_RESET_DATE = @$"
+ protected const string UPDATE_INFRASTRUCTURE_RESET_DATE = @$"
UPDATE {TABLE_NAME} SET LastResetDate = strftime('%Y-%m-%dT%H:%M:%f', 'now') WHERE InfrastructureId = @InfrastructureId
";
- }
}
diff --git a/NotoriousTest.Internal.TestSettings/NotoriousTest.Internal.TestSettings.csproj b/NotoriousTest.Internal.TestSettings/NotoriousTest.Internal.TestSettings.csproj
new file mode 100644
index 0000000..66cc5cd
--- /dev/null
+++ b/NotoriousTest.Internal.TestSettings/NotoriousTest.Internal.TestSettings.csproj
@@ -0,0 +1,19 @@
+
+
+ net8.0
+ NotoriousTest.Internal.TestSettings
+ [Internal] JSON-based test settings provider for NotoriousTest. Not intended for direct consumption — use the NotoriousTest package instead.
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NotoriousTest.Internal.TestSettings/TestSettingsProvider.cs b/NotoriousTest.Internal.TestSettings/TestSettingsProvider.cs
new file mode 100644
index 0000000..b63a1d2
--- /dev/null
+++ b/NotoriousTest.Internal.TestSettings/TestSettingsProvider.cs
@@ -0,0 +1,42 @@
+using Microsoft.Extensions.Configuration;
+using NotoriousTest.Core.Settings;
+
+namespace NotoriousTest.Internal.TestSettings;
+
+internal class TestSettingsProvider : ITestSettingsProvider
+{
+ private IConfiguration _cache;
+
+ public IConfiguration Find()
+ {
+ if (_cache == null)
+ {
+ string? settingsPath = FindFile("testsettings.json");
+
+
+ var configurationBuilder = new ConfigurationBuilder();
+ if (settingsPath != null) configurationBuilder.AddJsonFile(settingsPath);
+
+ _cache = configurationBuilder.Build();
+ }
+
+ return _cache;
+ }
+
+ public T? Get(string key) where T : new()
+ {
+ IConfigurationSection section = Find().GetSection(key);
+ if (!section.Exists())
+ return default;
+
+ var config = new T();
+ section.Bind(config);
+
+ return config;
+ }
+
+ private static string? FindFile(string fileName) =>
+ Directory
+ .EnumerateFiles(AppContext.BaseDirectory, fileName, SearchOption.AllDirectories)
+ .FirstOrDefault();
+}
diff --git a/NotoriousTest.Internal.Watchdog/DoggyDogWatchDog.cs b/NotoriousTest.Internal.Watchdog/DoggyDogWatchDog.cs
new file mode 100644
index 0000000..66b2c22
--- /dev/null
+++ b/NotoriousTest.Internal.Watchdog/DoggyDogWatchDog.cs
@@ -0,0 +1,95 @@
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using NotoriousTest.Core;
+using NotoriousTest.Core.Logger;
+using NotoriousTest.Core.Watchdog;
+using NotoriousTest.Internal.SqlLiteRegistry;
+
+namespace NotoriousTest.Internal.Watchdog;
+
+internal class DoggyDogWatchDog : IWatchDog
+{
+ private readonly DoggyDogWatchdogConfiguration _config;
+ private readonly ITestLogger _logger;
+ private readonly SqliteRegistryProviderConfiguration _registyConfiguration;
+
+ public DoggyDogWatchDog(SqliteRegistryProviderConfiguration registryConfiguration, ITestLogger logger,
+ DoggyDogWatchdogConfiguration config)
+ {
+ _registyConfiguration = registryConfiguration;
+ _logger = logger;
+ _config = config;
+ }
+
+ public Process Start(Assembly currentAssembly, int currentPid, EnvironmentId environmentId,
+ IEnumerable? runtimePaths)
+ {
+ string assemblyPath = currentAssembly.Location;
+ string? runtimesParams = runtimePaths == null ? null : string.Join("|", runtimePaths);
+
+ if (_config.ManualLaunch)
+ return WaitForDoggyDogToLaunch(currentPid, environmentId, assemblyPath, runtimesParams);
+ return LaunchDoggyDog(currentPid, environmentId, assemblyPath, runtimesParams) ??
+ throw new Exception("Could not launch DoggyDog");
+ }
+
+ public void SendSuccessSignal(EnvironmentId contextId) =>
+ File.WriteAllText(Path.Combine(Path.GetTempPath(), $"nt-{contextId.Value}.signal"), "OK");
+
+ private Process? LaunchDoggyDog(int currentPid, EnvironmentId contextId, string assemblyPath,
+ string? runtimesParams)
+ {
+ string watchdogPath = Path.Combine(AppContext.BaseDirectory,
+ RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "DoggyDog.exe" : "DoggyDog");
+
+ string runtimeParameter = runtimesParams == null ? "" : $"--runtimes \"{runtimesParams}\" ";
+ var process = Process.Start(new ProcessStartInfo
+ {
+ FileName = watchdogPath,
+ Arguments = $"--pid {currentPid} " +
+ $"--assembly \"{assemblyPath}\" " +
+ $"--connectionString \"{_registyConfiguration.ConnectionString}\" " +
+ $"--environment {contextId.Value} " +
+ runtimeParameter +
+ "--loglevel Info",
+ UseShellExecute = true,
+ CreateNoWindow = false
+ });
+
+
+ return process;
+ }
+
+ private Process WaitForDoggyDogToLaunch(int currentPid, EnvironmentId environmentId, string assemblyPath,
+ string? runtimesParams)
+ {
+ Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_PID", currentPid.ToString(), EnvironmentVariableTarget.User);
+ Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_ASSEMBLY", assemblyPath, EnvironmentVariableTarget.User);
+ Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_CONNECTIONSTRING", _registyConfiguration.ConnectionString,
+ EnvironmentVariableTarget.User);
+ Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_ENVIRONMENT", environmentId.Value.ToString(),
+ EnvironmentVariableTarget.User);
+ Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_RUNTIMES", runtimesParams, EnvironmentVariableTarget.User);
+ Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_LOGLEVEL", "Debug", EnvironmentVariableTarget.User);
+
+ Process? doggyDogProcess;
+ do
+ {
+ _logger.Log("Waiting for DoggyDog to launch...", environmentId);
+ doggyDogProcess = Process.GetProcessesByName("DoggyDog")?.FirstOrDefault();
+ Thread.Sleep(5000);
+ } while (doggyDogProcess == null);
+
+ return doggyDogProcess;
+ }
+
+ public static bool ReadSuccessSignal(EnvironmentId contextId)
+ {
+ string path = Path.Combine(Path.GetTempPath(), $"nt-{contextId.Value}.signal");
+ bool isSuccess = File.Exists(path);
+ if (isSuccess) File.Delete(path);
+
+ return isSuccess;
+ }
+}
diff --git a/NotoriousTest.Watchdog/DoggyDogWatchdogConfiguration.cs b/NotoriousTest.Internal.Watchdog/DoggyDogWatchdogConfiguration.cs
similarity index 79%
rename from NotoriousTest.Watchdog/DoggyDogWatchdogConfiguration.cs
rename to NotoriousTest.Internal.Watchdog/DoggyDogWatchdogConfiguration.cs
index 1d6cdaa..a65a46c 100644
--- a/NotoriousTest.Watchdog/DoggyDogWatchdogConfiguration.cs
+++ b/NotoriousTest.Internal.Watchdog/DoggyDogWatchdogConfiguration.cs
@@ -1,4 +1,4 @@
-namespace NotoriousTest.Core.Watchdog
+namespace NotoriousTest.Internal.Watchdog
{
public class DoggyDogWatchdogConfiguration
{
diff --git a/NotoriousTest.Internal.Watchdog/NotoriousTest.Internal.Watchdog.csproj b/NotoriousTest.Internal.Watchdog/NotoriousTest.Internal.Watchdog.csproj
new file mode 100644
index 0000000..cdd92e9
--- /dev/null
+++ b/NotoriousTest.Internal.Watchdog/NotoriousTest.Internal.Watchdog.csproj
@@ -0,0 +1,17 @@
+
+
+ net8.0
+ NotoriousTest.Internal.Watchdog
+ [Internal] Watchdog service for detecting and recovering stale test environments in NotoriousTest. Not intended for direct consumption — use the NotoriousTest package instead.
+ true
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/NotoriousTest.NoDoggyDog.slnf b/NotoriousTest.NoDoggyDog.slnf
index 5e472c9..a5a07f6 100644
--- a/NotoriousTest.NoDoggyDog.slnf
+++ b/NotoriousTest.NoDoggyDog.slnf
@@ -3,10 +3,10 @@
"path": "NotoriousTest.slnx",
"projects": [
"NotoriousTest.Core\\NotoriousTest.Core.csproj",
- "NotoriousTest.Runtime\\NotoriousTest.Runtime.csproj",
- "NotoriousTest.SqlLiteRegistry\\NotoriousTest.SqlLiteRegistry.csproj",
- "NotoriousTest.TestSettings\\NotoriousTest.TestSettings.csproj",
- "NotoriousTest.Watchdog\\NotoriousTest.Watchdog.csproj",
+ "NotoriousTest.Internal.Runtime\\NotoriousTest.Internal.Runtime.csproj",
+ "NotoriousTest.Internal.SqlLiteRegistry\\NotoriousTest.Internal.SqlLiteRegistry.csproj",
+ "NotoriousTest.Internal.TestSettings\\NotoriousTest.Internal.TestSettings.csproj",
+ "NotoriousTest.Internal.Watchdog\\NotoriousTest.Internal.Watchdog.csproj",
"NotoriousTest\\NotoriousTest.csproj",
"NotoriousTest.MSTest\\NotoriousTest.MSTest.csproj",
"NotoriousTest.NUnit\\NotoriousTest.NUnit.csproj",
diff --git a/NotoriousTest.Runtime/NotoriousTest.Runtime.csproj b/NotoriousTest.Runtime/NotoriousTest.Runtime.csproj
deleted file mode 100644
index 5ca8149..0000000
--- a/NotoriousTest.Runtime/NotoriousTest.Runtime.csproj
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- net8.0
- false
-
-
-
-
-
-
-
-
diff --git a/NotoriousTest.Runtime/RuntimeConfigurationEntity.cs b/NotoriousTest.Runtime/RuntimeConfigurationEntity.cs
deleted file mode 100644
index afd7cba..0000000
--- a/NotoriousTest.Runtime/RuntimeConfigurationEntity.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace NotoriousTest.Runtime
-{
- public record RuntimeConfigurationEntity(RuntimeOptions RuntimeOptions);
-
- public record RuntimeOptions(
- string Tfm,
- FrameworkEntry? Framework,
- FrameworkEntry[]? Frameworks
- );
-
- public record FrameworkEntry(string Name, string Version);
-}
diff --git a/NotoriousTest.Runtime/RuntimeConfigurationProvider.cs b/NotoriousTest.Runtime/RuntimeConfigurationProvider.cs
deleted file mode 100644
index 1db7dfb..0000000
--- a/NotoriousTest.Runtime/RuntimeConfigurationProvider.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using NotoriousTest.Core.Logger;
-using NotoriousTest.Core.Runtime;
-
-using System.Diagnostics;
-using System.Reflection;
-using System.Text.Json;
-
-namespace NotoriousTest.Runtime
-{
- public class RuntimeConfigurationProvider : IRuntime
- {
- private const string RuntimeFile = "runtimeconfig.json";
- private readonly ITestLogger _logger;
- private RuntimeConfiguration? _cache = null;
-
- private readonly JsonSerializerOptions JSON_OPTIONS = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
- public RuntimeConfigurationProvider(ITestLogger logger)
- {
- _logger = logger;
- }
-
- public RuntimeConfiguration? GetSupportedRuntimes(Assembly executingAssembly)
- {
- if (_cache != null) return _cache;
-
- string assemblyPath = executingAssembly.Location;
- string runtimePath = Path.ChangeExtension(assemblyPath, RuntimeFile);
-
- if (!File.Exists(runtimePath))
- return null;
-
-
- string json = File.ReadAllText(runtimePath);
-
-
- RuntimeConfigurationEntity? entity = JsonSerializer.Deserialize(json, JSON_OPTIONS);
- if (entity == null)
- return null;
-
- FrameworkEntry[]? frameworkEntries = entity.RuntimeOptions.Frameworks ?? [entity.RuntimeOptions.Framework!];
- SupportedFramework[]? frameworks = frameworkEntries.Select(ToDomain).ToArray();
-
- var result = new RuntimeConfiguration(entity.RuntimeOptions.Tfm, frameworks);
- _cache = result;
- return result;
- }
-
- private SupportedFramework ToDomain(FrameworkEntry entry) => new(entry.Name, entry.Version, GetNearestVersionDirectory(entry));
-
- private string? GetNearestVersionDirectory(FrameworkEntry framework)
- {
- string dotnetRoot = GetDotnetRoot();
-
- string frameworkPath = $"{dotnetRoot}/shared/{framework.Name}";
-
- string prefix = $"{new Version(framework.Version).Major}.{new Version(framework.Version).Minor}.";
- // Find the nearest version
- string? best = Directory.GetDirectories(frameworkPath)
- .Where(d => Path.GetFileName(d).StartsWith(prefix))
- .OrderByDescending(d => new Version(Path.GetFileName(d)))
- .FirstOrDefault();
-
- return best;
- }
- private string GetDotnetRoot()
- {
-
- string? dotnetRoot = Environment.GetEnvironmentVariable("DOTNET_ROOT");
-
- if (!string.IsNullOrWhiteSpace(dotnetRoot))
- return dotnetRoot;
-
- string mainModule = Process.GetCurrentProcess().MainModule!.FileName;
-
- // If the test project is self-contained (wich is rare), the main module will be the test executable itself.
- bool isNotSelfContained = Path.GetFileNameWithoutExtension(mainModule)
- .Equals("dotnet", StringComparison.OrdinalIgnoreCase);
-
- if (isNotSelfContained)
- return Path.GetDirectoryName(mainModule)!;
-
- return Path.Combine(
- Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles),
- "dotnet"
- );
- }
- }
-}
diff --git a/NotoriousTest.SqlLiteRegistry/InfrastructureRegistryEntryEntity.cs b/NotoriousTest.SqlLiteRegistry/InfrastructureRegistryEntryEntity.cs
deleted file mode 100644
index c5ea2be..0000000
--- a/NotoriousTest.SqlLiteRegistry/InfrastructureRegistryEntryEntity.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-using NotoriousTest.Core.Registry;
-
-using System.Globalization;
-using System.Text.Json;
-
-namespace NotoriousTest.SqlLiteRegistry
-{
- internal class InfrastructureRegistryEntryEntity
- {
- public string InfrastructureId { get; set; }
- public string InfrastructureType { get; set; }
- public string EnvironmentId { get; set; }
- public int ProcessID { get; set; }
- public string? Metadata { get; set; }
- public string? MetadataType { get; set; }
- public string? LastResetDate { get; set; }
- public string CreationDate { get; set; }
- public string UpdateDate { get; set; }
-
- internal static InfrastructureRegistryEntryEntity? FromDomain(InfrastuctureRegistryEntry entry)
- {
- return new InfrastructureRegistryEntryEntity()
- {
- InfrastructureId = entry.InfrastructureId.ToString(),
- InfrastructureType = entry.InfrastructureType.AssemblyQualifiedName,
- EnvironmentId = entry.EnvironmentId.ToString(),
- ProcessID = entry.ProcessID,
- Metadata = JsonSerializer.Serialize(entry.Metadata),
- MetadataType = entry.Metadata?.GetType().AssemblyQualifiedName,
- LastResetDate = entry.LastResetDate?.ToString("O")
- };
- }
-
- internal InfrastuctureRegistryEntry ToDomain()
- {
- Type? metadataType = null;
-
- if (MetadataType != null)
- {
- metadataType = Type.GetType(MetadataType);
- }
-
- Type? infraType = Type.GetType(InfrastructureType);
- if (infraType == null)
- {
- throw new TypeLoadException($"Unable to load type {InfrastructureType}");
- }
-
- return new InfrastuctureRegistryEntry()
- {
- InfrastructureId = Guid.Parse(InfrastructureId),
- InfrastructureType = Type.GetType(InfrastructureType),
- EnvironmentId = Guid.Parse(EnvironmentId),
- ProcessID = ProcessID,
- Metadata = !(Metadata is null) && !(metadataType is null)
- ? JsonSerializer.Deserialize(Metadata, metadataType)
- : null,
- LastResetDate = LastResetDate != null ? DateTime.Parse(LastResetDate, null, DateTimeStyles.RoundtripKind) : null,
- CreationDate = DateTime.Parse(CreationDate, null, DateTimeStyles.RoundtripKind),
- UpdateDate = DateTime.Parse(UpdateDate, null, DateTimeStyles.RoundtripKind),
- };
- }
- }
-}
diff --git a/NotoriousTest.SqlLiteRegistry/NotoriousTest.SqlLiteRegistry.csproj b/NotoriousTest.SqlLiteRegistry/NotoriousTest.SqlLiteRegistry.csproj
deleted file mode 100644
index ced8265..0000000
--- a/NotoriousTest.SqlLiteRegistry/NotoriousTest.SqlLiteRegistry.csproj
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
- net8.0
- false
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/NotoriousTest.SqlLiteRegistry/SqliteRegistryProvider.cs b/NotoriousTest.SqlLiteRegistry/SqliteRegistryProvider.cs
deleted file mode 100644
index 76ce971..0000000
--- a/NotoriousTest.SqlLiteRegistry/SqliteRegistryProvider.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-using Dapper;
-
-using Microsoft.Data.Sqlite;
-
-using NotoriousTest.Core;
-using NotoriousTest.Core.Registry;
-namespace NotoriousTest.SqlLiteRegistry
-{
- internal partial class SqliteRegistryProvider : IRegistry
- {
- private readonly SqliteRegistryProviderConfiguration _configuration;
- public event Action OnInfrastructureReset;
- public event Action OnInfrastructureDestroyed;
- public event Action OnInfrastructureCreated;
-
- public SqliteRegistryProvider(SqliteRegistryProviderConfiguration configuration)
- {
- _configuration = configuration;
- }
-
- private SqliteConnectionStringBuilder ConnectionString => new(_configuration.ConnectionString);
-
- private SqliteConnection Connection
- {
- get
- {
- var connection = new SqliteConnection(ConnectionString.ToString());
-
- if (connection.State != System.Data.ConnectionState.Open)
- {
- connection.Open();
- }
-
- connection.Execute("PRAGMA SYNCHRONOUS=NORMAL;PRAGMA JOURNAL_MODE=WAL;");
- return connection;
- }
- }
-
-
- public async Task Ensure()
- {
- string directory = Path.GetDirectoryName(ConnectionString.DataSource);
- if (!Directory.Exists(directory))
- {
- Directory.CreateDirectory(directory);
- }
-
- await using SqliteConnection connection = Connection;
-
- await connection.ExecuteAsync(ENSURE_REGISTRY);
- }
-
- public async Task Register(InfrastuctureRegistryEntry entry)
- {
- await using SqliteConnection connection = Connection;
- InfrastructureRegistryEntryEntity entity = await connection.QuerySingleAsync(REGISTER_INFRASTRUCTURE, InfrastructureRegistryEntryEntity.FromDomain(entry));
-
- return entity.ToDomain();
- }
-
- public async Task Remove(Guid id)
- {
- await using SqliteConnection connection = Connection;
-
- int deletedRows = await connection.ExecuteAsync(REMOVE_INFRASTRUCTURE, new { InfrastructureId = id.ToString() });
- return deletedRows > 0;
- }
-
- public async Task NotifyReset(Guid id)
- {
- await using SqliteConnection connection = Connection;
-
- await connection.ExecuteAsync(UPDATE_INFRASTRUCTURE_RESET_DATE, new { InfrastructureId = id.ToString() });
- }
-
- public async Task> GetByProcessId(int processId)
- {
- await using SqliteConnection connection = Connection;
-
- IEnumerable entries = await connection.QueryAsync(GET_BY_PROCESS_ID, new { ProcessID = processId });
- return entries.Select(entry => entry.ToDomain());
- }
-
- public async Task> GetByEnvironmentId(EnvironmentId environmentId)
- {
- await using SqliteConnection connection = Connection;
-
- IEnumerable entries = await connection.QueryAsync(GET_BY_ENVIRONMENT_ID, new { EnvironmentId = environmentId.Value.ToString() });
- return entries.Select(entry => entry.ToDomain());
- }
-
- public async Task Watch(EnvironmentId environmentId, CancellationToken ct)
- {
- var snapshot = (await GetByEnvironmentId(environmentId)).ToDictionary(x => x.InfrastructureId);
-
- do
- {
- IEnumerable infras = await GetByEnvironmentId(environmentId);
-
- foreach (InfrastuctureRegistryEntry infra in infras)
- {
- if (!snapshot.TryGetValue(infra.InfrastructureId, out var previous))
- {
- OnInfrastructureCreated?.Invoke(infra);
- }
-
- if (previous is not null && infra.LastResetDate != previous.LastResetDate)
- {
- OnInfrastructureReset?.Invoke(infra);
- }
- }
-
- foreach (var (key, infrastructure) in snapshot)
- {
- if (!infras.Any(i => i.InfrastructureId == infrastructure.InfrastructureId))
- {
- OnInfrastructureDestroyed?.Invoke(infrastructure);
- }
- }
-
- snapshot = infras.ToDictionary(x => x.InfrastructureId);
-
- try
- {
- await Task.Delay(10, ct);
- }
- catch (OperationCanceledException) { }
- } while (!ct.IsCancellationRequested);
- }
- }
-}
diff --git a/NotoriousTest.SqlLiteRegistry/SqliteRegistryProviderConfiguration.cs b/NotoriousTest.SqlLiteRegistry/SqliteRegistryProviderConfiguration.cs
deleted file mode 100644
index 98c0c55..0000000
--- a/NotoriousTest.SqlLiteRegistry/SqliteRegistryProviderConfiguration.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace NotoriousTest.SqlLiteRegistry
-{
- public class SqliteRegistryProviderConfiguration
- {
- public string ConnectionString { get; set; }
- }
-}
diff --git a/NotoriousTest.TestSettings/NotoriousTest.TestSettings.csproj b/NotoriousTest.TestSettings/NotoriousTest.TestSettings.csproj
deleted file mode 100644
index 6b02e26..0000000
--- a/NotoriousTest.TestSettings/NotoriousTest.TestSettings.csproj
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- net8.0
- false
-
-
-
-
-
-
-
-
-
-
diff --git a/NotoriousTest.TestSettings/TestSettingsProvider.cs b/NotoriousTest.TestSettings/TestSettingsProvider.cs
deleted file mode 100644
index 1fa81d1..0000000
--- a/NotoriousTest.TestSettings/TestSettingsProvider.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-using Microsoft.Extensions.Configuration;
-
-namespace NotoriousTest.Core.Settings
-{
- public class TestSettingsProvider : ITestSettingsProvider
- {
- private IConfiguration _cache;
- public IConfiguration Find()
- {
- if (_cache == null)
- {
- string? settingsPath = FindFile("testsettings.json");
-
-
- var configurationBuilder = new ConfigurationBuilder();
- if (settingsPath != null)
- {
- configurationBuilder.AddJsonFile(settingsPath);
-
- }
-
- _cache = configurationBuilder.Build();
-
- }
-
- return _cache;
- }
-
- public T? Get(string key) where T : new()
- {
- IConfigurationSection section = Find().GetSection(key);
- if (!section.Exists())
- return default;
-
- var config = new T();
- section.Bind(config);
-
- return config;
- }
- private static string? FindFile(string fileName)
- {
- return Directory
- .EnumerateFiles(AppContext.BaseDirectory, fileName, SearchOption.AllDirectories)
- .FirstOrDefault();
- }
- }
-}
diff --git a/NotoriousTest.UnitTests/NotoriousTest.UnitTests.csproj b/NotoriousTest.UnitTests/NotoriousTest.UnitTests.csproj
index fc50592..2644a4a 100644
--- a/NotoriousTest.UnitTests/NotoriousTest.UnitTests.csproj
+++ b/NotoriousTest.UnitTests/NotoriousTest.UnitTests.csproj
@@ -24,8 +24,8 @@
-
-
+
+
diff --git a/NotoriousTest.UnitTests/Registry/InfrastructureRegistryEntryEntityTests.cs b/NotoriousTest.UnitTests/Registry/InfrastructureRegistryEntryEntityTests.cs
index 69e110f..f02230c 100644
--- a/NotoriousTest.UnitTests/Registry/InfrastructureRegistryEntryEntityTests.cs
+++ b/NotoriousTest.UnitTests/Registry/InfrastructureRegistryEntryEntityTests.cs
@@ -1,7 +1,7 @@
using AwesomeAssertions;
using NotoriousTest.Core.Registry;
-using NotoriousTest.SqlLiteRegistry;
+using NotoriousTest.Internal.SqlLiteRegistry;
using System.Text.Json;
diff --git a/NotoriousTest.Watchdog/DoggyDogWatchDog.cs b/NotoriousTest.Watchdog/DoggyDogWatchDog.cs
deleted file mode 100644
index 147055b..0000000
--- a/NotoriousTest.Watchdog/DoggyDogWatchDog.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using NotoriousTest.Core;
-using NotoriousTest.Core.Logger;
-using NotoriousTest.Core.Watchdog;
-using NotoriousTest.SqlLiteRegistry;
-
-using System.Diagnostics;
-using System.Reflection;
-using System.Runtime.InteropServices;
-
-namespace NotoriousTest.Watchdog
-{
- public class DoggyDogWatchDog : IWatchDog
- {
- private readonly SqliteRegistryProviderConfiguration _registyConfiguration;
- private readonly ITestLogger _logger;
- private readonly DoggyDogWatchdogConfiguration _config;
-
- public DoggyDogWatchDog(SqliteRegistryProviderConfiguration registryConfiguration, ITestLogger logger, DoggyDogWatchdogConfiguration config)
- {
- _registyConfiguration = registryConfiguration;
- _logger = logger;
- _config = config;
- }
-
- public Process Start(Assembly currentAssembly, int currentPid, EnvironmentId environmentId, IEnumerable? runtimePaths)
- {
- string assemblyPath = currentAssembly.Location;
- string? runtimesParams = runtimePaths == null ? null : string.Join("|", runtimePaths);
-
- if (_config.ManualLaunch)
- return WaitForDoggyDogToLaunch(currentPid, environmentId, assemblyPath, runtimesParams);
- return LaunchDoggyDog(currentPid, environmentId, assemblyPath, runtimesParams) ?? throw new Exception("Could not launch DoggyDog");
- }
-
- private Process? LaunchDoggyDog(int currentPid, EnvironmentId contextId, string assemblyPath, string? runtimesParams)
- {
- string watchdogPath = Path.Combine(AppContext.BaseDirectory, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "DoggyDog.exe" : "DoggyDog");
-
- string runtimeParameter = runtimesParams == null ? "" : $"--runtimes \"{runtimesParams}\" ";
- var process = Process.Start(new ProcessStartInfo
- {
- FileName = watchdogPath,
- Arguments = $"--pid {currentPid} " +
- $"--assembly \"{assemblyPath}\" " +
- $"--connectionString \"{_registyConfiguration.ConnectionString}\" " +
- $"--environment {contextId.Value} " +
- runtimeParameter +
- "--loglevel Info",
- UseShellExecute = true,
- CreateNoWindow = false,
- });
-
-
- return process;
- }
-
- private Process WaitForDoggyDogToLaunch(int currentPid, EnvironmentId environmentId, string assemblyPath, string? runtimesParams)
- {
- Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_PID", currentPid.ToString(), EnvironmentVariableTarget.User);
- Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_ASSEMBLY", assemblyPath, EnvironmentVariableTarget.User);
- Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_CONNECTIONSTRING", _registyConfiguration.ConnectionString, EnvironmentVariableTarget.User);
- Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_ENVIRONMENT", environmentId.Value.ToString(), EnvironmentVariableTarget.User);
- Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_RUNTIMES", runtimesParams, EnvironmentVariableTarget.User);
- Environment.SetEnvironmentVariable("DOGGYDOG_DEBUG_LOGLEVEL", "Debug", EnvironmentVariableTarget.User);
-
- Process? doggyDogProcess;
- do
- {
- _logger.Log("Waiting for DoggyDog to launch...", environmentId);
- doggyDogProcess = Process.GetProcessesByName("DoggyDog")?.FirstOrDefault();
- Thread.Sleep(5000);
-
- } while (doggyDogProcess == null);
-
- return doggyDogProcess;
- }
-
- public void SendSuccessSignal(EnvironmentId contextId) => File.WriteAllText(Path.Combine(Path.GetTempPath(), $"nt-{contextId.Value}.signal"), "OK");
-
- public static bool ReadSuccessSignal(EnvironmentId contextId)
- {
- string path = Path.Combine(Path.GetTempPath(), $"nt-{contextId.Value}.signal");
- bool isSuccess = File.Exists(path);
- if (isSuccess) File.Delete(path);
-
- return isSuccess;
- }
- }
-}
diff --git a/NotoriousTest.Watchdog/NotoriousTest.Watchdog.csproj b/NotoriousTest.Watchdog/NotoriousTest.Watchdog.csproj
deleted file mode 100644
index e695800..0000000
--- a/NotoriousTest.Watchdog/NotoriousTest.Watchdog.csproj
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- net8.0
- false
-
-
-
-
-
-
-
-
diff --git a/NotoriousTest.slnx b/NotoriousTest.slnx
index ab48a9d..3d21f2e 100644
--- a/NotoriousTest.slnx
+++ b/NotoriousTest.slnx
@@ -23,10 +23,10 @@
-
-
-
-
+
+
+
+
diff --git a/NotoriousTest/DI/DependencyInjectionConfigurator.cs b/NotoriousTest/DI/DependencyInjectionConfigurator.cs
index cc6ad08..bea5bc6 100644
--- a/NotoriousTest/DI/DependencyInjectionConfigurator.cs
+++ b/NotoriousTest/DI/DependencyInjectionConfigurator.cs
@@ -9,9 +9,10 @@
using NotoriousTest.Core.Settings;
using NotoriousTest.Core.Watchdog;
using NotoriousTest.Environments;
-using NotoriousTest.Runtime;
-using NotoriousTest.SqlLiteRegistry;
-using NotoriousTest.Watchdog;
+using NotoriousTest.Internal.Runtime;
+using NotoriousTest.Internal.SqlLiteRegistry;
+using NotoriousTest.Internal.TestSettings;
+using NotoriousTest.Internal.Watchdog;
namespace NotoriousTest.DI;
diff --git a/NotoriousTest/NotoriousTest.csproj b/NotoriousTest/NotoriousTest.csproj
index 5b9c055..d7993f8 100644
--- a/NotoriousTest/NotoriousTest.csproj
+++ b/NotoriousTest/NotoriousTest.csproj
@@ -18,10 +18,10 @@
-
-
-
-
+
+
+
+