Skip to content

Commit

Permalink
Support for optional passing of mongo-bin location
Browse files Browse the repository at this point in the history
  • Loading branch information
krippz committed Jul 7, 2016
1 parent 6444238 commit c3cf907
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 50 deletions.
10 changes: 5 additions & 5 deletions src/Mongo2Go/Helper/FolderSearch.cs
Expand Up @@ -20,7 +20,7 @@ public static string FindFolder(this string startPath, string searchPattern)
{
string currentPath = startPath;

foreach (var part in searchPattern.Split(new[] { @"\" }, StringSplitOptions.None))
foreach (var part in searchPattern.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None))
{
string[] matchesDirectory = Directory.GetDirectories(currentPath, part);
if (!matchesDirectory.Any())
Expand Down Expand Up @@ -56,14 +56,14 @@ private static string FindFolderUpwards(this string startPath, string searchPatt

internal static string RemoveLastPart(this string path)
{
if (!path.Contains(@"\"))
if (!path.Contains(Path.DirectorySeparatorChar))
{
return null;
}

List<string> parts = path.Split(new[] {@"\"}, StringSplitOptions.None).ToList();
List<string> parts = path.Split(new[] { Path.DirectorySeparatorChar }, StringSplitOptions.None).ToList();
parts.RemoveAt(parts.Count() - 1);
return string.Join(@"\", parts.ToArray());
return string.Join(Path.DirectorySeparatorChar.ToString(), parts.ToArray());
}

/// <summary>
Expand All @@ -79,7 +79,7 @@ public static string FinalizePath(string fileName)
}
else
{
finalPath = CurrentExecutingDirectory() + @"\" + fileName;
finalPath = Path.Combine (CurrentExecutingDirectory (), fileName);
finalPath = Path.GetFullPath(finalPath);
}

Expand Down
7 changes: 7 additions & 0 deletions src/Mongo2Go/Helper/IMongoBinaryLocator.cs
@@ -0,0 +1,7 @@
namespace Mongo2Go.Helper
{
public interface IMongoBinaryLocator
{
string ResolveBinariesDirectory ();
}
}
37 changes: 37 additions & 0 deletions src/Mongo2Go/Helper/MongoBinaryLocator.cs
@@ -0,0 +1,37 @@
using System;

namespace Mongo2Go.Helper
{

public class MongoBinaryLocator : IMongoBinaryLocator
{
private string nugetPrefix = System.IO.Path.Combine ("packages", "Mongo2Go*");
private string searchPattern = "";

public MongoBinaryLocator (string binSearchPattern)
{
if (string.IsNullOrEmpty (binSearchPattern)) {
throw new ArgumentException ("Missing the search pattern for finding the mongoDb binaries.", "binSearchPattern");
}

searchPattern = binSearchPattern;
}

public string ResolveBinariesDirectory ()
{
// 1st: path when installed via nuget
// 2nd: path when started from solution
string binariesFolder = FolderSearch.CurrentExecutingDirectory ().FindFolderUpwards (System.IO.Path.Combine (nugetPrefix, searchPattern)) ??
FolderSearch.CurrentExecutingDirectory ().FindFolderUpwards (searchPattern);

if (binariesFolder == null) {
throw new MonogDbBinariesNotFoundException (string.Format (
"Could not find Mongo binaries using {0}. We walk up the directories {1} levels from {2}",
searchPattern,
FolderSearch.MaxLevelOfRecursion,
FolderSearch.CurrentExecutingDirectory ()));
}
return binariesFolder;
}
}
}
2 changes: 1 addition & 1 deletion src/Mongo2Go/Helper/MongoDbProcessStarter.cs
Expand Up @@ -17,7 +17,7 @@ public IMongoDbProcess Start(string binariesDirectory, string dataDirectory, int
/// </summary>
public IMongoDbProcess Start(string binariesDirectory, string dataDirectory, int port, bool doNotKill)
{
string fileName = @"{0}\{1}".Formatted(binariesDirectory, MongoDbDefaults.MongodExecutable);
string fileName = @"{0}{1}{2}".Formatted(binariesDirectory, System.IO.Path.DirectorySeparatorChar.ToString(), MongoDbDefaults.MongodExecutable);
string arguments = @"--dbpath ""{0}"" --port {1} --nohttpinterface --nojournal".Formatted(dataDirectory, port);

WrappedProcess wrappedProcess = ProcessControl.ProcessFactory(fileName, arguments);
Expand Down
2 changes: 2 additions & 0 deletions src/Mongo2Go/Mongo2Go.csproj
Expand Up @@ -107,6 +107,8 @@
<Compile Include="State.cs">
<DependentUpon>MongoDbRunner.cs</DependentUpon>
</Compile>
<Compile Include="Helper\MongoBinaryLocator.cs" />
<Compile Include="Helper\IMongoBinaryLocator.cs" />
<Compile Include="Helper\UnixPortWatcher.cs" />
<Compile Include="Helper\PortWatcherFactory.cs" />
</ItemGroup>
Expand Down
60 changes: 19 additions & 41 deletions src/Mongo2Go/MongoDbRunner.cs
Expand Up @@ -12,9 +12,7 @@ public partial class MongoDbRunner : IDisposable
private readonly IFileSystem _fileSystem;
private readonly string _dataDirectoryWithPort;
private readonly int _port;

private const string BinariesSearchPattern = @"packages\Mongo2Go*\tools\mongodb-win32*\bin";
private const string BinariesSearchPatternSolution = @"tools\mongodb-win32*\bin";
private readonly IMongoBinaryLocator _mongoBin;

/// <summary>
/// State of the current MongoDB instance
Expand All @@ -31,14 +29,14 @@ public partial class MongoDbRunner : IDisposable
/// On dispose: kills them and deletes their data directory
/// </summary>
/// <remarks>Should be used for integration tests</remarks>
public static MongoDbRunner Start(string dataDirectory = MongoDbDefaults.DataDirectory)
public static MongoDbRunner Start(string mongoBinSearchPattern = @"tools\mongodb-win32*\bin", string dataDirectory = MongoDbDefaults.DataDirectory)
{
return new MongoDbRunner(PortPool.GetInstance, new FileSystem(), new MongoDbProcessStarter(), dataDirectory);
return new MongoDbRunner(PortPool.GetInstance, new FileSystem(), new MongoDbProcessStarter(), new MongoBinaryLocator (mongoBinSearchPattern), dataDirectory);
}

internal static MongoDbRunner StartUnitTest(IPortPool portPool, IFileSystem fileSystem, IMongoDbProcessStarter processStarter)
internal static MongoDbRunner StartUnitTest(IPortPool portPool, IFileSystem fileSystem, IMongoDbProcessStarter processStarter, IMongoBinaryLocator mongoBin)
{
return new MongoDbRunner(portPool, fileSystem, processStarter, MongoDbDefaults.DataDirectory);
return new MongoDbRunner(portPool, fileSystem, processStarter, mongoBin, MongoDbDefaults.DataDirectory);
}

/// <summary>
Expand All @@ -48,39 +46,40 @@ internal static MongoDbRunner StartUnitTest(IPortPool portPool, IFileSystem file
/// Should be used for local debugging only
/// WARNING: one single instance on one single machine is not a suitable setup for productive environments!!!
/// </remarks>
public static MongoDbRunner StartForDebugging(string dataDirectory = MongoDbDefaults.DataDirectory)
public static MongoDbRunner StartForDebugging(string mongoBinSearchPattern = @"tools\mongodb-win32*\bin", string dataDirectory = MongoDbDefaults.DataDirectory)
{
return new MongoDbRunner(new ProcessWatcher(), new PortWatcher(), new FileSystem(), new MongoDbProcessStarter(), dataDirectory);
return new MongoDbRunner(new ProcessWatcher(), new PortWatcher(), new FileSystem(), new MongoDbProcessStarter(), new MongoBinaryLocator(mongoBinSearchPattern), dataDirectory);
}

internal static MongoDbRunner StartForDebuggingUnitTest(IProcessWatcher processWatcher, IPortWatcher portWatcher, IFileSystem fileSystem, IMongoDbProcessStarter processStarter)
internal static MongoDbRunner StartForDebuggingUnitTest(IProcessWatcher processWatcher, IPortWatcher portWatcher, IFileSystem fileSystem, IMongoDbProcessStarter processStarter, IMongoBinaryLocator mongoBin)
{
return new MongoDbRunner(processWatcher, portWatcher, fileSystem, processStarter, MongoDbDefaults.DataDirectory);
return new MongoDbRunner(processWatcher, portWatcher, fileSystem, processStarter,mongoBin, MongoDbDefaults.DataDirectory);
}

/// <summary>
/// Executes Mongoimport on the associated MongoDB Instace
/// </summary>
public void Import(string database, string collection, string inputFile, bool drop)
{
MongoImportExport.Import(BinariesDirectory, _port, database, collection, inputFile, drop);
MongoImportExport.Import(_mongoBin.ResolveBinariesDirectory(), _port, database, collection, inputFile, drop);
}

/// <summary>
/// Executes Mongoexport on the associated MongoDB Instace
/// </summary>
public void Export(string database, string collection, string outputFile)
{
MongoImportExport.Export(BinariesDirectory, _port, database, collection, outputFile);
MongoImportExport.Export(_mongoBin.ResolveBinariesDirectory(), _port, database, collection, outputFile);
}

/// <summary>
/// usage: local debugging
/// </summary>
private MongoDbRunner(IProcessWatcher processWatcher, IPortWatcher portWatcher, IFileSystem fileSystem, IMongoDbProcessStarter processStarter, string dataDirectory)
private MongoDbRunner(IProcessWatcher processWatcher, IPortWatcher portWatcher, IFileSystem fileSystem, IMongoDbProcessStarter processStarter,IMongoBinaryLocator mongoBin, string dataDirectory)
{
_fileSystem = fileSystem;
_port = MongoDbDefaults.DefaultPort;
_mongoBin = mongoBin;

ConnectionString = "mongodb://localhost:{0}/".Formatted(_port);

Expand All @@ -96,50 +95,29 @@ private MongoDbRunner(IProcessWatcher processWatcher, IPortWatcher portWatcher,
}

_fileSystem.CreateFolder(dataDirectory);
_fileSystem.DeleteFile(@"{0}\{1}".Formatted(dataDirectory, MongoDbDefaults.Lockfile));
_mongoDbProcess = processStarter.Start(BinariesDirectory, dataDirectory, _port, true);
_fileSystem.DeleteFile(@"{0}{1}{2}".Formatted(dataDirectory, System.IO.Path.DirectorySeparatorChar.ToString (), MongoDbDefaults.Lockfile));
_mongoDbProcess = processStarter.Start(_mongoBin.ResolveBinariesDirectory(), dataDirectory, _port, true);

State = State.Running;
}

/// <summary>
/// usage: integration tests
/// </summary>
private MongoDbRunner(IPortPool portPool, IFileSystem fileSystem, IMongoDbProcessStarter processStarter, string dataDirectory)
private MongoDbRunner(IPortPool portPool, IFileSystem fileSystem, IMongoDbProcessStarter processStarter, IMongoBinaryLocator mongoBin, string dataDirectory)
{
_fileSystem = fileSystem;
_port = portPool.GetNextOpenPort();
_mongoBin = mongoBin;

ConnectionString = "mongodb://localhost:{0}/".Formatted(_port);

_dataDirectoryWithPort = "{0}_{1}".Formatted(dataDirectory, _port);
_fileSystem.CreateFolder(_dataDirectoryWithPort);
_fileSystem.DeleteFile(@"{0}\{1}".Formatted(_dataDirectoryWithPort, MongoDbDefaults.Lockfile));
_mongoDbProcess = processStarter.Start(BinariesDirectory, _dataDirectoryWithPort, _port);
_fileSystem.DeleteFile(@"{0}{1}{2}".Formatted(_dataDirectoryWithPort, System.IO.Path.DirectorySeparatorChar.ToString(), MongoDbDefaults.Lockfile));
_mongoDbProcess = processStarter.Start(_mongoBin.ResolveBinariesDirectory(), _dataDirectoryWithPort, _port);

State = State.Running;
}

private static string BinariesDirectory
{
get
{
// 1st: path when installed via nuget
// 2nd: path when started from solution
string binariesFolder = FolderSearch.CurrentExecutingDirectory().FindFolderUpwards(BinariesSearchPattern) ??
FolderSearch.CurrentExecutingDirectory().FindFolderUpwards(BinariesSearchPatternSolution);

if (binariesFolder == null)
{
throw new MonogDbBinariesNotFoundException(string.Format(
"Could not find Mongo binaries using {0} or {1}. We walk up the directories {2} levels from {3}",
BinariesSearchPattern,
BinariesSearchPatternSolution,
FolderSearch.MaxLevelOfRecursion,
FolderSearch.CurrentExecutingDirectory()));
}
return binariesFolder;
}
}
}
}
3 changes: 3 additions & 0 deletions src/Mongo2GoTests/Mongo2GoTests.csproj
Expand Up @@ -98,6 +98,9 @@
<Name>Mongo2Go</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\nuget.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand Down
13 changes: 10 additions & 3 deletions src/Mongo2GoTests/Runner/RunnerTests.cs
Expand Up @@ -16,6 +16,7 @@ public class when_instanciating_the_runner_for_integration_test
static Mock<IPortPool> portPoolMock;
static Mock<IFileSystem> fileSystemMock;
static Mock<IMongoDbProcessStarter> processStarterMock;
static Mock<IMongoBinaryLocator> binaryLocatorMock;

static readonly string exptectedDataDirectory = "{0}_{1}".Formatted(MongoDbDefaults.DataDirectory, MongoDbDefaults.TestStartPort + 1);
static readonly string exptectedLogfile = @"{0}_{1}\{2}".Formatted(MongoDbDefaults.DataDirectory, MongoDbDefaults.TestStartPort + 1, MongoDbDefaults.Lockfile);
Expand All @@ -32,9 +33,12 @@ public class when_instanciating_the_runner_for_integration_test
processStarterMock = new Mock<IMongoDbProcessStarter>();
processStarterMock.Setup(m => m.Start(Moq.It.IsAny<string>(), Moq.It.IsAny<string>(), Moq.It.IsAny<int>())).Returns(processMock.Object);
binaryLocatorMock = new Mock<IMongoBinaryLocator> ();
};

Because of = () => runner = MongoDbRunner.StartUnitTest(portPoolMock.Object, fileSystemMock.Object, processStarterMock.Object);
Because of = () => runner = MongoDbRunner.StartUnitTest(portPoolMock.Object, fileSystemMock.Object, processStarterMock.Object, binaryLocatorMock.Object);

It should_create_the_data_directory = () => fileSystemMock.Verify(x => x.CreateFolder(exptectedDataDirectory), Times.Exactly(1));
It should_delete_old_lock_file = () => fileSystemMock.Verify(x => x.DeleteFile(exptectedLogfile), Times.Exactly(1));
Expand All @@ -53,6 +57,7 @@ public class when_instanciating_the_runner_for_local_debugging
static Mock<IProcessWatcher> processWatcherMock;
static Mock<IFileSystem> fileSystemMock;
static Mock<IMongoDbProcessStarter> processStarterMock;
static Mock<IMongoBinaryLocator> binaryLocatorMock;

static readonly string exptectedLogfile = @"{0}\{1}".Formatted(MongoDbDefaults.DataDirectory, MongoDbDefaults.Lockfile);

Expand All @@ -68,10 +73,12 @@ public class when_instanciating_the_runner_for_local_debugging
var processMock = new Mock<IMongoDbProcess>();
processStarterMock = new Mock<IMongoDbProcessStarter>();
processStarterMock.Setup(m => m.Start(Moq.It.IsAny<string>(), MongoDbDefaults.DataDirectory, MongoDbDefaults.DefaultPort, true)).Returns(processMock.Object);
processStarterMock.Setup(m => m.Start(Moq.It.IsAny<string>(), MongoDbDefaults.DataDirectory, MongoDbDefaults.DefaultPort, true)).Returns(processMock.Object);
binaryLocatorMock = new Mock<IMongoBinaryLocator> ();
};

Because of = () => runner = MongoDbRunner.StartForDebuggingUnitTest(processWatcherMock.Object, portWatcherMock.Object, fileSystemMock.Object, processStarterMock.Object);
Because of = () => runner = MongoDbRunner.StartForDebuggingUnitTest(processWatcherMock.Object, portWatcherMock.Object, fileSystemMock.Object, processStarterMock.Object, binaryLocatorMock.Object);

It should_check_for_already_running_process = () => processWatcherMock.Verify(x => x.IsProcessRunning(MongoDbDefaults.ProcessName), Times.Exactly(1));
It should_check_the_default_port = () => portWatcherMock.Verify(x => x.IsPortAvailable(MongoDbDefaults.DefaultPort), Times.Exactly(1));
Expand Down

0 comments on commit c3cf907

Please sign in to comment.