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

Validate ASM installations before loading #10621

Merged
merged 2 commits into from
May 4, 2020
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
174 changes: 163 additions & 11 deletions src/Tools/DynamoShapeManager/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,144 @@ public static class Utilities
/// </summary>
private static readonly List<string> ProductsWithASM = new List<string>() { "Revit", "Civil", "Robot Structural Analysis", "FormIt" };

#region ASM DLLs per version (to be kept in sync with LibG)

private static readonly ISet<string> ASM224DllNames = new HashSet<string>()
{
"TBB.DLL",
"TBBMALLOC.DLL",
"TSPLINES6A.DLL",
"ASMMATRIX224A.DLL",
"ASMBASE224A.DLL",
"ASMLAW224A.DLL",
"ASMKERN224A.DLL",
"ASMGA224A.DLL",
"ASMINTR224A.DLL",
"ASMTOPT224A.DLL",
"ASMCT224A.DLL",
"ASMCSTR224A.DLL",
"ASMEULR224A.DLL",
"ASMBOOL224A.DLL",
"ASMFCT224A.DLL",
"ASMLOPT224A.DLL",
"ASMRB224A.DLL",
"ASMRBI224A.DLL",
"ASMAHL224A.DLL",
"ASMOFST224A.DLL",
"ASMREM224A.DLL",
"ASMCOVR224A.DLL",
"ASMSKIN224A.DLL",
"ASMSBOOL224A.DLL",
"ASMBLND224A.DLL",
"ASMDATAX224A.DLL",
"ASMHEAL224A.DLL",
"ASMSWP224A.DLL",
"ASMDEFM224A.DLL",
"ASMFREC224A.DLL",
"ASMNPCH224A.DLL",
"ASMOPER224A.DLL",
"ASMIMPORT224A.DLL",
"ASMLOP224A.DLL",
"ASMSBAP224A.DLL",
"ASMSHL224A.DLL",
"ASMTWK224A.DLL",
"ASMPID224A.DLL",
"ASMUFLD224A.DLL",
"ASMWELD224A.DLL"
};

private static readonly ISet<string> ASM225DllNames = new HashSet<string>()
{
"TBB.DLL",
"TBBMALLOC.DLL",
"TSPLINES7A.DLL",
"ASMMATRIX225A.DLL",
"ASMBASE225A.DLL",
"ASMLAW225A.DLL",
"ASMKERN225A.DLL",
"ASMGA225A.DLL",
"ASMINTR225A.DLL",
"ASMTOPT225A.DLL",
"ASMCT225A.DLL",
"ASMCSTR225A.DLL",
"ASMEULR225A.DLL",
"ASMBOOL225A.DLL",
"ASMFCT225A.DLL",
"ASMLOPT225A.DLL",
"ASMRB225A.DLL",
"ASMRBI225A.DLL",
"ASMAHL225A.DLL",
"ASMOFST225A.DLL",
"ASMREM225A.DLL",
"ASMCOVR225A.DLL",
"ASMSKIN225A.DLL",
"ASMSBOOL225A.DLL",
"ASMBLND225A.DLL",
"ASMDATAX225A.DLL",
"ASMHEAL225A.DLL",
"ASMSWP225A.DLL",
"ASMDEFM225A.DLL",
"ASMFREC225A.DLL",
"ASMNPCH225A.DLL",
"ASMOPER225A.DLL",
"ASMIMPORT225A.DLL",
"ASMLOP225A.DLL",
"ASMSBAP225A.DLL",
"ASMSHL225A.DLL",
"ASMTWK225A.DLL",
"ASMPID225A.DLL",
"ASMUFLD225A.DLL",
"ASMWELD225A.DLL"
};

private static readonly ISet<string> ASM226DllNames = new HashSet<string>()
{
"TBB.DLL",
"TBBMALLOC.DLL",
"TSPLINES8A.DLL",
"ASMBASE226A.DLL",
"ASMLAW226A.DLL",
"ASMKERN226A.DLL",
"ASMGA226A.DLL",
"ASMINTR226A.DLL",
"ASMTOPT226A.DLL",
"ASMCT226A.DLL",
"ASMCSTR226A.DLL",
"ASMEULR226A.DLL",
"ASMBOOL226A.DLL",
"ASMFCT226A.DLL",
"ASMLOPT226A.DLL",
"ASMRBASE226A.DLL",
"ASMRBI226A.DLL",
"ASMAHL226A.DLL",
"ASMOFST226A.DLL",
"ASMREM226A.DLL",
"ASMCOVR226A.DLL",
"ASMSKIN226A.DLL",
"ASMSBOOL226A.DLL",
"ASMBLND226A.DLL",
"ASMDATAX226A.DLL",
"ASMHEAL226A.DLL",
"ASMSWP226A.DLL",
"ASMDEFM226A.DLL",
"ASMFREC226A.DLL",
"ASMNPCH226A.DLL",
"ASMOPER226A.DLL",
"ASMIMPORT226A.DLL",
"ASMLOP226A.DLL",
"ASMSBAP226A.DLL",
"ASMSHL226A.DLL",
"ASMTWK226A.DLL",
"ASMPID226A.DLL",
"ASMUFLD226A.DLL",
"ASMWELD226A.DLL",
"ADPSDKWRAPPER.DLL",
"ADPSDKUI.DLL",
"ADPSDKCORE.DLL"
};

#endregion

#region public properties
public static readonly string GeometryFactoryAssembly = "LibG.ProtoInterface.dll";
public static readonly string PreloaderAssembly = "LibG.AsmPreloader.Managed.dll";
Expand Down Expand Up @@ -452,20 +590,34 @@ private static IEnumerable GetAsmInstallations(string rootFolder)
var methodParams = new object[] { ProductsWithASM, ASMFileMask };
var installs = installationsMethod.Invoke(null, methodParams) as IEnumerable;

//filter install locations missing tbb and tbbmalloc.dll
return installs.Cast<KeyValuePair<string, Tuple<int, int, int, int>>>().Where(install =>
{
var files = Directory.EnumerateFiles(install.Key, "tbb*.dll").Select(x=>System.IO.Path.GetFileName(x));
if (files.Contains("tbb.dll") && files.Contains("tbbmalloc.dll"))
{
return true;
}
return false;

});
IsASMInstallationComplete(Directory.EnumerateFiles(install.Key), install.Value.Item1)
);
}


/// <summary>
/// Given ASM installation files and its version, checks if all of the required files are present.
/// Note: This method is internal in order to testable.
/// </summary>
/// <param name="filePaths">Files found on an ASM installation location.</param>
/// <param name="majorVersion">Major version of ASM found in the specified location.</param>
/// <returns>Whether the files represent a complete ASM installation or not.</returns>
internal static bool IsASMInstallationComplete(IEnumerable<string> filePaths, int majorVersion)
{
var fileNames = filePaths.Select(path => Path.GetFileName(path).ToUpper());
switch (majorVersion)
{
case 226:
return !ASM226DllNames.Except(fileNames).Any();
case 225:
return !ASM225DllNames.Except(fileNames).Any();
case 224:
return !ASM224DllNames.Except(fileNames).Any();
default:
// We don't know this version so it's safest to assume it's not complete.
return false;
}
}

/// <summary>
/// Extracts version of ASM dlls from a path by scanning for ASM dlls in the path.
Expand Down
50 changes: 49 additions & 1 deletion test/DynamoCoreTests/libGPreloaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,13 @@
namespace Dynamo.Tests
{
[TestFixture]
public class libGPreloaderTests
public class libGPreloaderTests : UnitTestBase
{
private List<string> LoadListFromCsv(string fileName)
{
var path = Path.Combine(TestDirectory, @"core\libGPreloader", fileName);
return File.ReadAllText(path).Split(';').ToList();
}

[Test]
public void GetInstalledASMVersions2_FindsVersionedLibGFolders()
Expand Down Expand Up @@ -443,5 +448,48 @@ public void PreloaderThatDoesNotFindASMDoesNotThrow()
var preloader = new Preloader(Path.GetTempPath(), new[] { new Version(999, 999, 999) });
});
}

[Test]
public void ASM226InstallationsAreValidated()
{
var incomplete226List = LoadListFromCsv("incomplete226List.csv");
Assert.IsFalse(DynamoShapeManager.Utilities.IsASMInstallationComplete(incomplete226List, 226));
// Add missing DLLs. Now the the installation should be valid.
incomplete226List.Add("tsplines8A.dll");
incomplete226List.Add("AdpSDKUI.dll");
Assert.IsTrue(DynamoShapeManager.Utilities.IsASMInstallationComplete(incomplete226List, 226));
}

[Test]
public void ASM225InstallationsAreValidated()
{
var incomplete225List = LoadListFromCsv("incomplete225List.csv");
Assert.IsFalse(DynamoShapeManager.Utilities.IsASMInstallationComplete(incomplete225List, 225));
// Add missing DLLs. Now the the installation should be valid.
incomplete225List.Add("tsplines7A.dll");
incomplete225List.Add("ASMMATRIX225A.dll");
incomplete225List.Add("ASMRB225A.dll");
Assert.IsTrue(DynamoShapeManager.Utilities.IsASMInstallationComplete(incomplete225List, 225));
}

[Test]
public void ASM224InstallationsAreValidated()
{
var incomplete224List = LoadListFromCsv("incomplete224List.csv");
Assert.IsFalse(DynamoShapeManager.Utilities.IsASMInstallationComplete(incomplete224List, 224));
// Add missing DLLs. Now the the installation should be valid.
incomplete224List.Add("tbb.dll");
incomplete224List.Add("tbbmalloc.dll");
incomplete224List.Add("tsplines6A.dll");
incomplete224List.Add("ASMMATRIX224A.dll");
incomplete224List.Add("ASMRB224A.dll");
Assert.IsTrue(DynamoShapeManager.Utilities.IsASMInstallationComplete(incomplete224List, 224));
}

[Test]
public void UnknownASMVersionInstallationsAreDiscarded()
{
Assert.IsFalse(DynamoShapeManager.Utilities.IsASMInstallationComplete(new List<string>(), 0));
}
}
}
1 change: 1 addition & 0 deletions test/core/libGPreloader/incomplete224List.csv

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions test/core/libGPreloader/incomplete225List.csv

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions test/core/libGPreloader/incomplete226List.csv

Large diffs are not rendered by default.