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

GeometryFactoryPath lookup should be more consistent with other preloader utilities. #9493

Merged
merged 6 commits into from
Feb 20, 2019
Merged
Show file tree
Hide file tree
Changes from 2 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
25 changes: 22 additions & 3 deletions src/Tools/DynamoShapeManager/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ internal static string RemapOldLibGPathToNewVersionPath(string preloaderLocation
/// <summary>
/// Call this method to resolve full path to GeometryFactoryAssembly
/// assembly, given the root folder and the version. This method throws
/// an exception if either of the folders/assembly cannot be found.
/// an exception if either of the folders or the exact version of the assembly cannot be found.
/// </summary>
/// <param name="rootFolder">Full path of the directory that contains
/// LibG_xxx folder, where 'xxx' represents the library version. In a
Expand All @@ -368,7 +368,7 @@ public static string GetGeometryFactoryPath(string rootFolder, LibraryVersion ve
/// <summary>
/// Call this method to resolve full path to GeometryFactoryAssembly
/// assembly, given the root folder and the version. This method throws
/// an exception if either of the folders/assembly cannot be found.
/// an exception if either of the folders or the exact version of the assembly cannot be found.
/// </summary>
/// <param name="rootFolder">Full path of the directory that contains
/// LibG_xxx_y_z folder, where 'xxx y z' represents the library version of asm. In a
Expand Down Expand Up @@ -410,7 +410,26 @@ public static string GetGeometryFactoryPath2(string rootFolder, Version version)

return assemblyPath;
}

/// <summary>
/// This method will return the path to the GeometryFactory assembly location for a requested version of the geometry library.
/// This method is tolerant to the requested version in that it will attempt to locate an exact or lower version of the GeometryFactory assembly.
/// </summary>
/// <param name="rootFolder">Full path of the directory that contains
/// LibG_xxx_y_z folder, where 'xxx y z' represents the library version of asm. In a
/// typical setup this would be the same directory that contains Dynamo
/// core modules. This must represent a valid directory - it cannot be null.</param>
/// <param name="tolerantVersion">Version number of the targeted geometry library.
/// If the resulting assembly does not exist, this method will look for a lower version match.
/// This parameter cannot be null. </param>
/// <returns>The full path to GeometryFactoryAssembly assembly.</returns>
///
public static string GetGeometryFactoryPathTolerant(string rootFolder, Version tolerantVersion){
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved
if(tolerantVersion != null && rootFolder != null)
{
return Path.Combine(Utilities.GetLibGPreloaderLocation(tolerantVersion, rootFolder), Utilities.GeometryFactoryAssembly);
Copy link
Contributor

@QilongTang QilongTang Feb 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code itself looks fine but I was expecting us to merge some code between GetGeometryFactoryPath2 and GetGeometryFactoryPathTolerant because in the end either DynamoCore or our client would only be available to call one of them. But for now the code path between these two are quite different. From the API name I would assume this one is only doing the fall back logic as addition? Do you think if we also still need those folder check logic in this new API?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I find these two methods both potentially useful - they do different things, and I think it's always useful to have an explicit method to avoid unknown behavior which is why I did not obsolete the other method.

  2. Sandbox AFAIK does not call these methods at all.

  3. The end result to the client is like you said that it appears it does a fallback - it DOES have different edge case behavior though - it returns a empty string instead of exceptions when it encounters bad input - that's kind of what I was asking about in the test cases? I'm okay with the more slow failure because this is a tolerant version of the method, but open to other opinions for sure.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I don't mean to obsolete the other one. I thought we want to include the folder check logic in the new API as well because of some legacy bug, if you think it is OK and good enough for the clients then this version should be fine to use. Do you plan to make any change in client code as an example usage of this API later when nuget is up?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually don't see any reason to keep GetGeometryFactoryPath2 after the addition of this new API and I think we should add the folder check exceptions to the new API. I don't see reasons to remove them from here. GetGeometryFactoryPath2 can give unexpected results (in combination with other API's) like we've seen in the Revit case so I think it should be obsoleted.

}
return string.Empty;
}

private static IEnumerable GetAsmInstallations(string rootFolder)
{
Expand Down
98 changes: 98 additions & 0 deletions test/DynamoCoreTests/libGPreloaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,104 @@ public void GetLibGPreloaderLocation_libGVersionFallback()
libG22500path.Delete(true);
}

[Test]
public void GetGeometryFactoryPathTolerant_libGVersionFallback()
{
var versions = new List<Version>()
{
new Version(225,0,0)
};

var mockedInstalledASMs = new Dictionary<string, Tuple<int, int, int, int>>()
{

{"revit_2020_InstallLocation" ,Tuple.Create<int,int,int,int>(225,2,0,0)},
};

var targetVersion = new Version(225, 2, 0);

// mock a folder with libASMLibVersionToVersion folders with correct names
var foundPath = "";
var rootFolder = Path.Combine(Path.GetTempPath(), "LibGTest");
// both versions of libG exist
var libG22440path = System.IO.Directory.CreateDirectory(Path.Combine(rootFolder, "LibG_224_4_0"));
var libG22500path = System.IO.Directory.CreateDirectory(Path.Combine(rootFolder, "LibG_225_0_0"));

var foundVersion = DynamoShapeManager.Utilities.GetInstalledAsmVersion2(
versions, ref foundPath, rootFolder, (path) => { return mockedInstalledASMs; });

// The found ASM version in this case is a fallback of lowest version within same major which should be 225.2.0
Assert.AreEqual(targetVersion, foundVersion);
Assert.AreEqual("revit_2020_InstallLocation", foundPath);

// The found libG preloader version in this case is another fallback of closest version below 225.3.0
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved
Assert.AreEqual(libG22500path.FullName.ToLower(), DynamoShapeManager.Utilities.GetLibGPreloaderLocation(foundVersion, rootFolder).ToLower());

//assert that the geometryFactoryTolerant method returns the path of the lib225_0_0 path.
Assert.AreEqual(Path.Combine(libG22500path.FullName,DynamoShapeManager.Utilities.GeometryFactoryAssembly).ToLower(),
DynamoShapeManager.Utilities.GetGeometryFactoryPathTolerant(rootFolder, targetVersion).ToLower());
//assert the non tolerant version throws
Assert.Throws<DirectoryNotFoundException>(() => { DynamoShapeManager.Utilities.GetGeometryFactoryPath2(rootFolder, targetVersion); });
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved

// cleanup
libG22440path.Delete(true);
libG22500path.Delete(true);
}

[Test]
public void GetGeometryFactoryPathTolerant_NoMatch()
{
var versions = new List<Version>()
{
new Version(225,0,0)
};

var mockedInstalledASMs = new Dictionary<string, Tuple<int, int, int, int>>()
{

{"someInstallWithNoMatchingASM" ,Tuple.Create<int,int,int,int>(224,0,0,0)},
};

var targetVersion = new Version(225, 2, 0);
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved

// mock a folder with libASMLibVersionToVersion folders with correct names
var foundPath = "";
var rootFolder = Path.Combine(Path.GetTempPath(), "LibGTest");
// both versions of libG exist
var libG22500path = System.IO.Directory.CreateDirectory(Path.Combine(rootFolder, "LibG_225_0_0"));
var libGTestPath = new DirectoryInfo(Path.Combine(rootFolder, "LibG_224_24_24"));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You end up not using this, right? Also, the "both versions of libG exist" comment in this test threw me off as I was reading through it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @scottmitchell will fix this.

var foundVersion = DynamoShapeManager.Utilities.GetInstalledAsmVersion2(
versions, ref foundPath, rootFolder, (path) => { return mockedInstalledASMs; });

// There is no match, so found version is null.
Assert.AreEqual(null, foundVersion);
// There is no match, so path to ASM is null.
Assert.AreEqual(string.Empty, foundPath);

// when passed null as a version, GetLibGPreloaderLocation will return LibG_0_0_0
Assert.IsTrue(DynamoShapeManager.Utilities.GetLibGPreloaderLocation(foundVersion, rootFolder).ToLower().Contains("libg_0_0_0"));


//when passed a null version this method should return empty string - as the geometry path was not located
Assert.AreEqual(string.Empty,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please see these cases - looking for feedback if these make sense.

DynamoShapeManager.Utilities.GetGeometryFactoryPathTolerant(rootFolder, null));

//when passed a null root directory this method should return empty string - as a valid root directory is required.
Assert.AreEqual(string.Empty,
DynamoShapeManager.Utilities.GetGeometryFactoryPathTolerant(null, new Version(224, 24, 24)));

// when passed a non null, non matching version this method should return a path to the version that was supplied -
// but it will likely fail later.
Assert.AreEqual(Path.Combine(libGTestPath.FullName, DynamoShapeManager.Utilities.GeometryFactoryAssembly).ToLower(),
DynamoShapeManager.Utilities.GetGeometryFactoryPathTolerant(rootFolder, new Version(224,24,24)).ToLower());
aparajit-pratap marked this conversation as resolved.
Show resolved Hide resolved

//assert the non tolerant version throws
Assert.Throws<DirectoryNotFoundException>(() => { DynamoShapeManager.Utilities.GetGeometryFactoryPath2(rootFolder, new Version(224, 24, 24)); });

// cleanup
libG22500path.Delete(true);
}


[Test]
public void GetInstalledASMVersions2_FindsVersionedLibGFolders_WithRootFolderFallback()
Expand Down