Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crossplat #11

Merged
merged 4 commits into from
Jul 24, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/Mongo2Go/Helper/FileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,11 @@ public void DeleteFile(string fullFileName)
File.Delete(fullFileName);
}
}

public void MakeFileExecutable (string path)
{
//when on linux or osx we must set the executeble flag on mongo binarys
File.SetAttributes (path, (FileAttributes)((int)File.GetAttributes (path) | 0x80000000));
}
}
}
10 changes: 5 additions & 5 deletions src/Mongo2Go/Helper/FolderSearch.cs
Original file line number Diff line number Diff line change
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
1 change: 1 addition & 0 deletions src/Mongo2Go/Helper/IFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ public interface IFileSystem
void CreateFolder(string path);
void DeleteFolder(string path);
void DeleteFile(string fullFileName);
void MakeFileExecutable (string path );
}
}
7 changes: 7 additions & 0 deletions src/Mongo2Go/Helper/IMongoBinaryLocator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Mongo2Go.Helper
{
public interface IMongoBinaryLocator
{
string Directory { get; }
}
}
49 changes: 49 additions & 0 deletions src/Mongo2Go/Helper/MongoBinaryLocator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System;
using System.IO;

namespace Mongo2Go.Helper
{

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

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 Directory {
get {
if (string.IsNullOrEmpty (binFolder)){
return binFolder = ResolveBinariesDirectory ();
} else {
return binFolder;
}
}
}

private 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
Original file line number Diff line number Diff line change
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: 1 addition & 1 deletion src/Mongo2Go/Helper/PortPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public int GetNextOpenPort()
{
lock (_lock)
{
PortWatcher portWatcher = new PortWatcher();
IPortWatcher portWatcher = PortWatcherFactory.CreatePortWatcher();
int newAvailablePort = portWatcher.FindOpenPort(_startPort);

_startPort = newAvailablePort + 1;
Expand Down
29 changes: 29 additions & 0 deletions src/Mongo2Go/Helper/PortWatcherFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;

namespace Mongo2Go.Helper
{
public class PortWatcherFactory
{
public static IPortWatcher CreatePortWatcher()
{
IPortWatcher portwatcher = null;

switch (Environment.OSVersion.Platform)
{
case PlatformID.Unix:
portwatcher = new UnixPortWatcher ();
break;

default:
portwatcher = new PortWatcher ();
break;
}

return portwatcher;
}
}
}
47 changes: 47 additions & 0 deletions src/Mongo2Go/Helper/UnixPortWatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.Net;
using System.Net.Sockets;

namespace Mongo2Go.Helper
{

public class UnixPortWatcher : IPortWatcher
{
public int FindOpenPort (int startPort)
{
int port = startPort;
do {
if (IsPortAvailable (port)) {
break;
}

if (port == MongoDbDefaults.TestStartPort + 100) {
throw new NoFreePortFoundException ();
}

++port;

} while (true);

return port;
}

public bool IsPortAvailable (int portNumber)
{
bool result = false;

TcpListener tcpListener = new TcpListener (IPAddress.Loopback, portNumber);
try {
tcpListener.Start ();
} catch (SocketException) {
result = false;

} finally
{
tcpListener.Stop ();
result = true;
}

return result;
}
}
}
4 changes: 4 additions & 0 deletions src/Mongo2Go/Mongo2Go.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@
<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>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Expand Down
71 changes: 33 additions & 38 deletions src/Mongo2Go/MongoDbRunner.cs
Original file line number Diff line number Diff line change
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,44 @@ 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.Directory, _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.Directory, _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;

MakeMongoBinarysExecutable();

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

Expand All @@ -96,49 +99,41 @@ 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.Directory, 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;

MakeMongoBinarysExecutable();

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.Directory, _dataDirectoryWithPort, _port);

State = State.Running;
}

private static string BinariesDirectory
private void MakeMongoBinarysExecutable()
{
get
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
// 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;
_fileSystem.MakeFileExecutable (System.IO.Path.Combine (_mongoBin.Directory, MongoDbDefaults.MongodExecutable));
_fileSystem.MakeFileExecutable (System.IO.Path.Combine (_mongoBin.Directory, MongoDbDefaults.MongoExportExecutable));
_fileSystem.MakeFileExecutable (System.IO.Path.Combine (_mongoBin.Directory, MongoDbDefaults.MongoImportExecutable));
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/Mongo2GoTests/Mongo2GoTests.csproj
Original file line number Diff line number Diff line change
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
Loading