Skip to content

Commit

Permalink
DYN-7889: Improve parsing and compatibility of user-provided dynamo/h…
Browse files Browse the repository at this point in the history
…ost versions (#15682)
  • Loading branch information
dnenov authored Nov 22, 2024
1 parent 3e20369 commit 550354c
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 22 deletions.
32 changes: 31 additions & 1 deletion src/DynamoPackages/PackageManagerSearchElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -377,8 +377,11 @@ private List<VersionInformation> TransformVersionsToVersionInformation(Greg.Resp
/// </summary>
internal static bool IsVersionCompatible(Greg.Responses.Compatibility compatibility, Version version)
{
// Start by trimming away the Revision value
version = VersionUtilities.NormalizeVersion(version);

// Check if the version is explicitly listed
bool isListedInVersions = compatibility.versions?.Contains(version.ToString()) ?? false;
bool isListedInVersions = NormalizeAndContain(compatibility.versions, version);

// Parse min and max values, if provided, and check for valid range
bool isWithinMinMax = false;
Expand Down Expand Up @@ -421,6 +424,33 @@ internal static bool IsVersionCompatible(Greg.Responses.Compatibility compatibil
return isListedInVersions || isWithinMinMax;
}

// Aligns Dynamo's fully-defined version with Compatibility Matrix partial version strings
internal static bool NormalizeAndContain(IEnumerable<string> versionStrings, Version version)
{
if (versionStrings == null) return false;

// Normalize the input version to a 3-part format (Major.Minor.Build)
var normalizedVersion = VersionUtilities.NormalizeVersion(version);

foreach (var v in versionStrings)
{
// Parse and normalize each version string
var parsedVersion = VersionUtilities.Parse(v);
if (parsedVersion != null)
{
var normalizedParsedVersion = VersionUtilities.NormalizeVersion(parsedVersion);

// Compare the normalized versions
if (normalizedVersion.Equals(normalizedParsedVersion))
{
return true;
}
}
}

return false;
}

// Method to find Dynamo compatibility based on other hosts in the compatibilityMatrix
internal static Greg.Responses.Compatibility GetDynamoCompatibilityFromHost(List<Greg.Responses.Compatibility> compatibilityMatrix, Dictionary<string, Dictionary<string, string>> map = null)
{
Expand Down
16 changes: 15 additions & 1 deletion src/DynamoUtilities/VersionUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public static Version Parse(string version)
// Try parsing directly; if successful, return the parsed version
if (Version.TryParse(version, out Version parsedVersion))
{
return parsedVersion;
return NormalizeVersion(parsedVersion);
}

// If parsing failed, pad the version string
Expand Down Expand Up @@ -128,5 +128,19 @@ private static string AppendWildcardVersion(string major, string minor = WILDCAR
{
return $"{major}.{minor}.{patch}";
}

/// <summary>
/// Helper method to normalize versions to a 3-part format
/// </summary>
/// <param name="version">A potentially partial version</param>
/// <returns></returns>
internal static Version NormalizeVersion(Version version)
{
return new Version(
version.Major,
version.Minor == -1 ? 0 : version.Minor,
version.Build == -1 ? 0 : version.Build
);
}
}
}
24 changes: 23 additions & 1 deletion test/DynamoCoreTests/VersionUtilitiesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ public void ParseVersionSafely_LongVersion_ReturnsParsedVersion()
Version result = VersionUtilities.Parse(version);

// Assert
Assert.AreEqual(new Version(2019, 1, 2, 0), result, "Expected version '2019.1.2.0' when input is '2019.1.2.0'.");
Assert.AreEqual(new Version(2019, 1, 2), result, "Expected version '2019.1.2' when input is '2019.1.2.0'.");
}

[Test]
Expand Down Expand Up @@ -258,6 +258,28 @@ public void ParseWildCard_TooManyComponents_ReturnsNull()
Assert.IsNull(result, "Expected null when input has too many components '1.2.3.4.*'.");
}

[Test]
public void NormalizeVersion_ShouldReturnCorrectlyNormalizedVersion()
{
// Test case 1: Partial version with only Major
Version.TryParse("3.0", out Version input1);
var expected1 = new Version(3, 0, 0);
var result1 = VersionUtilities.NormalizeVersion(input1);
Assert.AreEqual(expected1, result1, $"Expected {expected1} but got {result1}");

// Test case 2: Partial version with Major and Minor
Version.TryParse("3.1", out Version input2);
var expected2 = new Version(3, 1, 0);
var result2 = VersionUtilities.NormalizeVersion(input2);
Assert.AreEqual(expected2, result2, $"Expected {expected2} but got {result2}");

// Test case 3: Full version that doesn't need normalization
var input3 = new Version(3, 1, 2);
var expected3 = new Version(3, 1, 2);
var result3 = VersionUtilities.NormalizeVersion(input3);
Assert.AreEqual(expected3, result3, $"Expected {expected3} but got {result3}");
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -1146,12 +1146,12 @@ public void TestComputeVersionSingleCompatibility()


[Test]
[TestCase("2.9.9", false)] // Incompatible Dynamo version
[TestCase("3.0.0", true)] // Compatible Dynamo version
[TestCase("3.1.0", true)] // Compatible Dynamo version
[TestCase("3.2.2", true)] // Compatible Dynamo version
[TestCase("3.3.0", false)] // Incompatible Dynamo version
[TestCase("3.4.0", false)] // Incompatible Dynamo version
[TestCase("2.9.9.2114", false)] // Incompatible Dynamo version
[TestCase("3.0.0.2114", true)] // Compatible Dynamo version
[TestCase("3.1.0.2114", true)] // Compatible Dynamo version
[TestCase("3.2.2.2114", true)] // Compatible Dynamo version
[TestCase("3.3.0.2114", false)] // Incompatible Dynamo version
[TestCase("3.4.0.2114", false)] // Incompatible Dynamo version
public void TestComputeMultipleSingleCompatibility(string dynamoVersion, bool expectedCompatibility)
{
// Arrange
Expand All @@ -1171,21 +1171,21 @@ public void TestComputeMultipleSingleCompatibility(string dynamoVersion, bool ex
}

[Test]
[TestCase("2.19", true)] // Compatible Dynamo version
[TestCase("2.19.1", false)] // Incompatible Dynamo version
[TestCase("2.19.5", true)] // Compatible Dynamo version
[TestCase("2.19.6", true)] // Compatible Dynamo version
[TestCase("3.0.0", true)] // Compatible Dynamo version
[TestCase("3.1.0", true)] // Compatible Dynamo version
[TestCase("3.2.2", true)] // Compatible Dynamo version
[TestCase("3.3.0", false)] // Incompatible Dynamo version
[TestCase("2.19.0.2114", true)] // Compatible Dynamo version
[TestCase("2.19.1.2114", false)] // Incompatible Dynamo version
[TestCase("2.19.5.2114", true)] // Compatible Dynamo version
[TestCase("2.19.6.2114", true)] // Compatible Dynamo version
[TestCase("3.0.0.2114", true)] // Compatible Dynamo version
[TestCase("3.1.0.2114", true)] // Compatible Dynamo version
[TestCase("3.2.2.2114", true)] // Compatible Dynamo version
[TestCase("3.3.0.1232", false)] // Incompatible Dynamo version
[TestCase("3.4.0.6825", true)] // Compatible Dynamo version
public void TestComputeMinMaxMultipleSingleCompatibility(string dynamoVersion, bool expectedCompatibility)
{
// Arrange
var hostOnlyCompatibilityMatrix = new List<Greg.Responses.Compatibility>
{
new Greg.Responses.Compatibility { name = "dynamo", min = "2.19.5", max = "3.2.2", versions = new List<string> { "2.19", "3.4.0.6825" } }
new Greg.Responses.Compatibility { name = "dynamo", min = "2.19.5", max = "3.2.2", versions = new List<string> { "2.19", "3.4.0" } }
};

var versionToTest = new Version(dynamoVersion);
Expand All @@ -1198,16 +1198,16 @@ public void TestComputeMinMaxMultipleSingleCompatibility(string dynamoVersion, b
Assert.AreEqual(expectedCompatibility, result, $"Expected compatibility to be {expectedCompatibility} for version {dynamoVersion}.");
}

[TestCase("3.1", true)] // Compatible Dynamo version
[TestCase("3.1.0", false)] // Incompatible Dynamo version
[TestCase("3.4.0", false)] // Incompatible Dynamo version
[TestCase("3.1.0.2123", true)] // Compatible Dynamo version
[TestCase("3.4.0.6825", true)] // Compatible Dynamo version
[TestCase("2.19.0.6825", false)] // Incompatible Dynamo version
[TestCase("2.0.0.6825", true)] // Compatible Dynamo version
public void TestPreciseSingleCompatibility(string dynamoVersion, bool expectedCompatibility)
{
// Arrange
var hostOnlyCompatibilityMatrix = new List<Greg.Responses.Compatibility>
{
new Greg.Responses.Compatibility { name = "dynamo", versions = new List<string> { "3.1", "3.4.0.6825" } }
new Greg.Responses.Compatibility { name = "dynamo", versions = new List<string> { "3.1", "3.4.0", "2" } }
};

var versionToTest = new Version(dynamoVersion);
Expand Down Expand Up @@ -1593,6 +1593,28 @@ public void IsVersionCompatible_InValidMaxRange_ReturnsTrueForVersionInsideOfMaj
"Expected compatibility to be true when major version is greater than Max major version and there is an invalid max range.");
}

[Test]
public void NormalizeAndCompareVersionStringList_ShouldSucceed()
{

var versions = new List<string> { "2.1.0", "2.3.0", "2", "2.4.*", "afs" };
var version = new Version(2,1,0,1252);

var isListedInVersions = PackageManagerSearchElement.NormalizeAndContain(versions, version);
Assert.IsTrue(isListedInVersions);
}

[Test]
public void NormalizeAndCompareVersionStringList_ShouldFail()
{

var versions = new List<string> { "2.19" };
var version = new Version(2, 19, 1, 1252);

var isListedInVersions = PackageManagerSearchElement.NormalizeAndContain(versions, version);
Assert.IsFalse(isListedInVersions);
}

#endregion

}
Expand Down

0 comments on commit 550354c

Please sign in to comment.