diff --git a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs index c3bf3fb38e..43524c8d80 100644 --- a/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs +++ b/src/ServiceControl.Audit.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs @@ -76,7 +76,11 @@ public static async Task Stop(CancellationToken cancellationToken = default) await semaphoreSlim.WaitAsync(cancellationToken); try { - embeddedDatabase?.Dispose(); + if (embeddedDatabase != null) + { + await embeddedDatabase.DisposeAndDeleteServerTempFiles(cancellationToken); + } + embeddedDatabase = null; } finally diff --git a/src/ServiceControl.Persistence.Tests.RavenDB/EmbeddedDatabaseExtensionsTests.cs b/src/ServiceControl.Persistence.Tests.RavenDB/EmbeddedDatabaseExtensionsTests.cs new file mode 100644 index 0000000000..df7ca0a16a --- /dev/null +++ b/src/ServiceControl.Persistence.Tests.RavenDB/EmbeddedDatabaseExtensionsTests.cs @@ -0,0 +1,48 @@ +namespace ServiceControl.Persistence.Tests; + +using System.IO; +using System.Linq; +using NUnit.Framework; +using TestHelper; + +[TestFixture] +public class EmbeddedDatabaseExtensionsTests +{ + [Test] + public void DeleteServerTempFiles_should_delete_only_files_of_the_given_process() + { + var root = Path.Combine(TestContext.CurrentContext.WorkDirectory, "Tests", Path.GetRandomFileName()); + var tempDirectory = Path.Combine(root, "RavenDBServer", "Temp"); + Directory.CreateDirectory(tempDirectory); + + try + { + string[] owned = ["ravendb-100-1-0000000000000000001.journal-a", "ravendb-100-1-compression.0000000000.buffers-b"]; + string[] others = ["ravendb-1000-1-0000000000000000001.journal-c", "ravendb-200-1-0000000000000000001.journal-d"]; + var binary = Path.Combine(root, "RavenDBServer", "Raven.Server.dll"); + + foreach (var name in owned.Concat(others)) + { + File.WriteAllText(Path.Combine(tempDirectory, name), string.Empty); + } + File.WriteAllText(binary, string.Empty); + + EmbeddedDatabaseExtensions.DeleteServerTempFiles(tempDirectory, 100); + + Assert.Multiple(() => + { + Assert.That(owned.Select(n => Path.Combine(tempDirectory, n)), Has.None.Matches(File.Exists)); + Assert.That(others.Select(n => Path.Combine(tempDirectory, n)), Has.All.Matches(File.Exists)); + Assert.That(File.Exists(binary), Is.True); + }); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + + [Test] + public void DeleteServerTempFiles_should_ignore_missing_directory() => + Assert.DoesNotThrow(() => EmbeddedDatabaseExtensions.DeleteServerTempFiles(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()), 100)); +} diff --git a/src/ServiceControl.Persistence.Tests.RavenDB/PersistenceTestsContext.cs b/src/ServiceControl.Persistence.Tests.RavenDB/PersistenceTestsContext.cs index 84800e06bf..9fe9798356 100644 --- a/src/ServiceControl.Persistence.Tests.RavenDB/PersistenceTestsContext.cs +++ b/src/ServiceControl.Persistence.Tests.RavenDB/PersistenceTestsContext.cs @@ -66,6 +66,7 @@ public async Task TearDown() } await embeddedServer.DeleteDatabase(databaseName); + await embeddedServer.DeleteDatabase(((RavenPersisterSettings)PersistenceSettings).ThroughputDatabaseName); } public PersistenceSettings PersistenceSettings { get; private set; } diff --git a/src/ServiceControl.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs b/src/ServiceControl.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs index 49b3cddb56..1bcaaf8e59 100644 --- a/src/ServiceControl.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs +++ b/src/ServiceControl.Persistence.Tests.RavenDB/SharedEmbeddedServer.cs @@ -80,7 +80,11 @@ public static async Task Stop(CancellationToken cancellationToken = default) await semaphoreSlim.WaitAsync(cancellationToken); try { - embeddedDatabase?.Dispose(); + if (embeddedDatabase != null) + { + await embeddedDatabase.DisposeAndDeleteServerTempFiles(cancellationToken); + } + embeddedDatabase = null; } finally diff --git a/src/TestHelper/EmbeddedDatabaseExtensions.cs b/src/TestHelper/EmbeddedDatabaseExtensions.cs index 92cf85fb0f..764c219c69 100644 --- a/src/TestHelper/EmbeddedDatabaseExtensions.cs +++ b/src/TestHelper/EmbeddedDatabaseExtensions.cs @@ -1,6 +1,7 @@ namespace TestHelper; using System; +using System.IO; using System.Threading; using System.Threading.Tasks; using Raven.Client.ServerWide.Operations; @@ -25,4 +26,33 @@ await store.Maintenance.Server.SendAsync( new DeleteDatabasesOperation(dbName, hardDelete: true, timeToWaitForConfirmation: TimeSpan.FromSeconds(30)), cancellationToken); } + + // Delete only the stopped server's PID batch so concurrent runs sharing this folder are untouched. + public static async Task DisposeAndDeleteServerTempFiles(this EmbeddedDatabase database, CancellationToken cancellationToken = default) + { + int processId; + try + { + processId = await EmbeddedServer.Instance.GetServerProcessIdAsync(cancellationToken); + } + finally + { + database.Dispose(); + } + + DeleteServerTempFiles(Path.Combine(Path.GetDirectoryName(typeof(EmbeddedDatabase).Assembly.Location)!, "RavenDBServer", "Temp"), processId); + } + + public static void DeleteServerTempFiles(string tempDirectory, int processId) + { + if (!Directory.Exists(tempDirectory)) + { + return; + } + + foreach (var file in Directory.EnumerateFiles(tempDirectory, $"ravendb-{processId}-*")) + { + File.Delete(file); + } + } }