Skip to content

Commit

Permalink
Make sure to delete the data directory if the runner fails to start
Browse files Browse the repository at this point in the history
  • Loading branch information
asimmon committed Aug 2, 2022
1 parent 9ed3475 commit 55044c6
Showing 1 changed file with 42 additions and 30 deletions.
72 changes: 42 additions & 30 deletions src/EphemeralMongo.Core/MongoRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace EphemeralMongo;

public sealed class MongoRunner : IDisposable
public sealed class MongoRunner
{
private readonly IFileSystem _fileSystem;
private readonly IPortFactory _portFactory;
Expand Down Expand Up @@ -33,36 +33,44 @@ public static IMongoRunner Run(MongoRunnerOptions? options = null)

private IMongoRunner RunInternal()
{
// Ensure data directory exists and has no existing MongoDB lock file
this._dataDirectory = this._options.DataDirectory ?? Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
this._fileSystem.CreateDirectory(this._dataDirectory);
try
{
// Find MongoDB and make it executable
var executablePath = this._executableLocator.FindMongoExecutablePath(this._options, MongoProcessKind.Mongod);
this._fileSystem.MakeFileExecutable(executablePath);

// https://stackoverflow.com/a/6857973/825695
var lockFilePath = Path.Combine(this._dataDirectory, "mongod.lock");
this._fileSystem.DeleteFile(lockFilePath);
// Ensure data directory exists and has no existing MongoDB lock file
this._dataDirectory = this._options.DataDirectory ?? Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
this._fileSystem.CreateDirectory(this._dataDirectory);

// Find MongoDB and make it executable
var executablePath = this._executableLocator.FindMongoExecutablePath(this._options, MongoProcessKind.Mongod);
this._fileSystem.MakeFileExecutable(executablePath);
// https://stackoverflow.com/a/6857973/825695
var lockFilePath = Path.Combine(this._dataDirectory, "mongod.lock");
this._fileSystem.DeleteFile(lockFilePath);

this._options.MongoPort = this._portFactory.GetRandomAvailablePort();
this._options.MongoPort = this._portFactory.GetRandomAvailablePort();

// Build MongoDB executable arguments
var arguments = string.Format(CultureInfo.InvariantCulture, "--dbpath \"{0}\" --port {1} --bind_ip 127.0.0.1", this._dataDirectory, this._options.MongoPort);
arguments += RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? string.Empty : " --tlsMode disabled";
arguments += this._options.UseSingleNodeReplicaSet ? " --replSet " + this._options.ReplicaSetName : string.Empty;
arguments += this._options.AdditionalArguments == null ? string.Empty : " " + this._options.AdditionalArguments;
// Build MongoDB executable arguments
var arguments = string.Format(CultureInfo.InvariantCulture, "--dbpath \"{0}\" --port {1} --bind_ip 127.0.0.1", this._dataDirectory, this._options.MongoPort);
arguments += RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? string.Empty : " --tlsMode disabled";
arguments += this._options.UseSingleNodeReplicaSet ? " --replSet " + this._options.ReplicaSetName : string.Empty;
arguments += this._options.AdditionalArguments == null ? string.Empty : " " + this._options.AdditionalArguments;

this._process = this._processFactory.CreateMongoProcess(this._options, MongoProcessKind.Mongod, executablePath, arguments);
this._process.Start();
this._process = this._processFactory.CreateMongoProcess(this._options, MongoProcessKind.Mongod, executablePath, arguments);
this._process.Start();

var connectionStringFormat = this._options.UseSingleNodeReplicaSet ? "mongodb://127.0.0.1:{0}/?connect=direct&replicaSet={1}&readPreference=primary" : "mongodb://127.0.0.1:{0}";
var connectionString = string.Format(CultureInfo.InvariantCulture, connectionStringFormat, this._options.MongoPort, this._options.ReplicaSetName);
var connectionStringFormat = this._options.UseSingleNodeReplicaSet ? "mongodb://127.0.0.1:{0}/?connect=direct&replicaSet={1}&readPreference=primary" : "mongodb://127.0.0.1:{0}";
var connectionString = string.Format(CultureInfo.InvariantCulture, connectionStringFormat, this._options.MongoPort, this._options.ReplicaSetName);

return new StartedMongoRunner(this, connectionString);
return new StartedMongoRunner(this, connectionString);
}
catch
{
this.Dispose(throwOnException: false);
throw;
}
}

public void Dispose()
private void Dispose(bool throwOnException)
{
var exceptions = new List<Exception>(1);

Expand All @@ -77,7 +85,8 @@ public void Dispose()

try
{
if (this._dataDirectory != null)
// Do not dispose data directory if it was a user input
if (this._dataDirectory != null && this._options.DataDirectory == null)
{
this._fileSystem.DeleteDirectory(this._dataDirectory);
}
Expand All @@ -87,13 +96,16 @@ public void Dispose()
exceptions.Add(ex);
}

if (exceptions.Count == 1)
if (throwOnException)
{
ExceptionDispatchInfo.Capture(exceptions[0]).Throw();
}
else if (exceptions.Count > 1)
{
throw new AggregateException(exceptions);
if (exceptions.Count == 1)
{
ExceptionDispatchInfo.Capture(exceptions[0]).Throw();
}
else if (exceptions.Count > 1)
{
throw new AggregateException(exceptions);
}
}
}

Expand Down Expand Up @@ -186,7 +198,7 @@ public void Dispose()
{
if (Interlocked.CompareExchange(ref this._isDisposed, 1, 0) == 0)
{
this._runner.Dispose();
this._runner.Dispose(throwOnException: true);
}
}
}
Expand Down

0 comments on commit 55044c6

Please sign in to comment.