Skip to content

Commit

Permalink
Merge pull request #224 from siemens/Bugfixes12/16/24
Browse files Browse the repository at this point in the history
Npm and Python jFrog bug fixes
  • Loading branch information
adityanarayanp authored Jan 10, 2025
2 parents b3fbc51 + cceeb67 commit 11bcece
Show file tree
Hide file tree
Showing 20 changed files with 714 additions and 192 deletions.
12 changes: 6 additions & 6 deletions src/AritfactoryUploader.UTest/ArtifactoryUploaderTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public async Task UploadPackageToRepo_InputEmptyCreds_ReturnsPackgeNotFound()
JfrogApi = "https://abc.jfrog.io/artifactory",
SrcRepoName = "org1-pythonhosted-pypi-remote-cache",
SrcRepoPathWithFullName = "org1-pythonhosted-pypi-remote-cache/6c/dd/a834df6482147d48e225a49515aabc28974ad5a4ca3215c18a882565b028/html5lib-1.1-py2.py3-none-any.whl",
PypiCompName = "html5lib-1.1-py2.py3-none-any.whl",
PypiOrNpmCompName = "html5lib-1.1-py2.py3-none-any.whl",
DestRepoName = "pypi-test",
ApiKey = "",
Email = "",
Expand Down Expand Up @@ -111,7 +111,7 @@ public async Task UploadPackageToRepo_WhenPackageInfoIsNull_ReturnsNotFoundRespo
var timeout = 10000;
var displayPackagesInfo = new DisplayPackagesInfo();
var jFrogServiceMock = new Mock<IJFrogService>();
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
jFrogServiceMock.Setup(x => x.GetPackageInfo(component))
.ReturnsAsync((AqlResult)null);
ArtfactoryUploader.jFrogService = jFrogServiceMock.Object;
// Act
Expand Down Expand Up @@ -140,7 +140,7 @@ public async Task UploadPackageToRepo_WhenPackageTypeIsClearedThirdPartyOrDevelo
var displayPackagesInfo = new DisplayPackagesInfo();
var jFrogServiceMock = new Mock<IJFrogService>();
var jfrogApicommunicationMock = new Mock<IJFrogApiCommunication>();
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
jFrogServiceMock.Setup(x => x.GetPackageInfo(component))
.ReturnsAsync(new AqlResult());
jfrogApicommunicationMock.Setup(x => x.CopyFromRemoteRepo(It.IsAny<ComponentsToArtifactory>()))
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK));
Expand Down Expand Up @@ -171,7 +171,7 @@ public async Task UploadPackageToRepo_WhenPackageTypeIsInternal_CallsMoveFromRep
var displayPackagesInfo = new DisplayPackagesInfo();
var jFrogServiceMock = new Mock<IJFrogService>();
var jfrogApicommunicationMock = new Mock<IJFrogApiCommunication>();
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
jFrogServiceMock.Setup(x => x.GetPackageInfo(component))
.ReturnsAsync(new AqlResult());
jfrogApicommunicationMock.Setup(x => x.MoveFromRepo(It.IsAny<ComponentsToArtifactory>()))
.ReturnsAsync(new HttpResponseMessage(HttpStatusCode.OK));
Expand Down Expand Up @@ -227,7 +227,7 @@ public async Task UploadPackageToRepo_WhenHttpRequestExceptionOccurs_ReturnsErro
var displayPackagesInfo = new DisplayPackagesInfo();
var jFrogServiceMock = new Mock<IJFrogService>();
var jfrogApicommunicationMock = new Mock<IJFrogApiCommunication>();
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
jFrogServiceMock.Setup(x => x.GetPackageInfo(component))
.ThrowsAsync(new HttpRequestException());
ArtfactoryUploader.jFrogService = jFrogServiceMock.Object;
ArtfactoryUploader.JFrogApiCommInstance = jfrogApicommunicationMock.Object;
Expand Down Expand Up @@ -257,7 +257,7 @@ public async Task UploadPackageToRepo_WhenInvalidOperationExceptionOccurs_Return
var displayPackagesInfo = new DisplayPackagesInfo();
var jFrogServiceMock = new Mock<IJFrogService>();
var jfrogApicommunicationMock = new Mock<IJFrogApiCommunication>();
jFrogServiceMock.Setup(x => x.GetPackageInfo(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
jFrogServiceMock.Setup(x => x.GetPackageInfo(component))
.ThrowsAsync(new InvalidOperationException());
ArtfactoryUploader.jFrogService = jFrogServiceMock.Object;
ArtfactoryUploader.JFrogApiCommInstance = jfrogApicommunicationMock.Object;
Expand Down
81 changes: 71 additions & 10 deletions src/AritfactoryUploader.UTest/PackageUploadHelperTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -406,20 +406,31 @@ public void GetUploadPackageDetails_CoversAllScenarios()
public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenPypiRepoExists_ReturnsArtifactoryRepoName()
{
// Arrange
Property prop1 = new Property
Property repoNameProperty = new Property
{
Name = Dataconstant.Cdx_ArtifactoryRepoName,
Value = "Reponame"
};
List<Property> properties = new List<Property>() { prop1 };
List<Property> properties = new List<Property>() { repoNameProperty };
var item = new Component
{
Purl = "pypi://example-package",
Properties = properties,
Name = "pypi component",
Version = "1.0.0"
};
AqlProperty pypiNameProperty = new AqlProperty
{
Key = "pypi.normalized.name",
Value = "pypi component"
};

AqlProperty pypiVersionProperty = new AqlProperty
{
Key = "pypi.version",
Value = "1.0.0"
};
List<AqlProperty> propertys = new List<AqlProperty> { pypiNameProperty, pypiVersionProperty };
//GetInternalComponentDataByRepo
var aqlResultList = new List<AqlResult>
{
Expand All @@ -428,22 +439,24 @@ public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenPypiRepoExists_Ret
Repo = "pypi-repo",
Path = "path/to/package",
Name = "pypi component-1.0.0",
Properties=propertys,
}
};
var jFrogServiceMock = new Mock<IJFrogService>();
jFrogServiceMock.Setup(x => x.GetInternalComponentDataByRepo(It.IsAny<string>())).ReturnsAsync(aqlResultList);

jFrogServiceMock.Setup(x => x.GetPypiComponentDataByRepo(It.IsAny<string>())).ReturnsAsync(aqlResultList);

PackageUploadHelper.jFrogService = jFrogServiceMock.Object;

// Act
var result = await PackageUploadHelper.GetSrcRepoDetailsForPyPiOrConanPackages(item);
var result = await PackageUploadHelper.GetSrcRepoDetailsForComponent(item);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual("pypi-repo", result.Repo);
Assert.AreEqual("path/to/package", result.Path);
}

public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenConanRepoExists_ReturnsArtifactoryRepoName()
public async static Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenConanRepoExists_ReturnsArtifactoryRepoName()
{
// Arrange
Property prop1 = new Property
Expand Down Expand Up @@ -474,7 +487,7 @@ public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenConanRepoExists_Re
PackageUploadHelper.jFrogService = jFrogServiceMock.Object;

// Act
var result = await PackageUploadHelper.GetSrcRepoDetailsForPyPiOrConanPackages(item);
var result = await PackageUploadHelper.GetSrcRepoDetailsForComponent(item);

// Assert
Assert.IsNotNull(result);
Expand All @@ -494,7 +507,7 @@ public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenNoRepoExists_Retur
PackageUploadHelper.jFrogService = jFrogServiceMock.Object;

// Act
var result = await PackageUploadHelper.GetSrcRepoDetailsForPyPiOrConanPackages(item);
var result = await PackageUploadHelper.GetSrcRepoDetailsForComponent(item);

// Assert
Assert.IsNull(result);
Expand Down Expand Up @@ -744,7 +757,7 @@ public async Task GetJfrogRepoInfoForAllTypePackages_GivenDestRepoNames_ReturnsA
}

[Test]
[TestCase("NPM", "source-repo/package-name/-/package-name-1.0.0.tgz?to=/destination-repo/package-name/-/package-name-1.0.0.tgz")]
[TestCase("NPM", "?to=/destination-repo//")]
[TestCase("NUGET", "source-repo/package-name.1.0.0.nupkg?to=/destination-repo/package-name.1.0.0.nupkg")]
[TestCase("MAVEN", "source-repo/package-name/1.0.0?to=/destination-repo/package-name/1.0.0")]
[TestCase("CONAN", "source-repo/?to=/destination-repo/")]
Expand Down Expand Up @@ -798,7 +811,7 @@ public void GetCopyURL_GivenInvalidComponentType_ReturnsEmptyString()


[Test]
[TestCase("NPM", "source-repo/package-name/-/package-name-1.0.0.tgz?to=/destination-repo/package-name/-/package-name-1.0.0.tgz")]
[TestCase("NPM", "?to=/destination-repo//")]
[TestCase("NUGET", "source-repo/package-name.1.0.0.nupkg?to=/destination-repo/package-name.1.0.0.nupkg")]
[TestCase("MAVEN", "source-repo/package-name/1.0.0?to=/destination-repo/package-name/1.0.0")]
[TestCase("CONAN", "source-repo/?to=/destination-repo/")]
Expand Down Expand Up @@ -849,5 +862,53 @@ public void GetMoveURL_GivenInvalidComponentType_ReturnsEmptyString()
// Assert
Assert.AreEqual(string.Empty, result);
}

[Test]
public async Task GetSrcRepoDetailsForPyPiOrConanPackages_WhenNpmRepoExists_ReturnsArtifactoryRepoName()
{
// Arrange
var repoNameProperty = new Property
{
Name = Dataconstant.Cdx_ArtifactoryRepoName,
Value = "npm-repo"
};
var properties = new List<Property> { repoNameProperty };
var item = new Component
{
Purl = "pkg:npm/example-package",
Properties = properties,
Name = "example-package",
Version = "1.0.0"
};
var aqlResultList = new List<AqlResult>
{
new AqlResult
{
Repo = "npm-repo",
Path = "path/to/package",
Name = "example-package-1.0.0",
Properties = new List<AqlProperty>
{
new AqlProperty { Key = "npm.name", Value = "example-package" },
new AqlProperty { Key = "npm.version", Value = "1.0.0" }
}
}
};

var jFrogServiceMock = new Mock<IJFrogService>();

jFrogServiceMock.Setup(x => x.GetNpmComponentDataByRepo(It.IsAny<string>())).ReturnsAsync(aqlResultList);

PackageUploadHelper.jFrogService = jFrogServiceMock.Object;


// Act
var result = await PackageUploadHelper.GetSrcRepoDetailsForComponent(item);

// Assert
Assert.IsNotNull(result);
Assert.AreEqual("npm-repo", result.Repo);
Assert.AreEqual("path/to/package", result.Path);
}
}
}
30 changes: 7 additions & 23 deletions src/ArtifactoryUploader/ArtifactoryUploader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,11 @@ public static void SetConfigurationValues()

private static async Task<AqlResult> GetPackageInfoWithRetry(IJFrogService jFrogService, ComponentsToArtifactory component)
{
async Task<AqlResult> TryGetPackageInfo(string srcRepo, string packageName, string path)
=> await jFrogService.GetPackageInfo(srcRepo, packageName, path);
async Task<AqlResult> TryGetPackageInfo(ComponentsToArtifactory component)
=> await jFrogService.GetPackageInfo(component);

var packageInfo = await TryGetPackageInfo(component.SrcRepoName, component.JfrogPackageName, component.Path);
var packageInfo = await TryGetPackageInfo(component);


// Handle DEBIAN package name mismatch
if (component.ComponentType == "DEBIAN" && packageInfo?.Name != component.JfrogPackageName)
Expand All @@ -124,32 +125,15 @@ async Task<AqlResult> TryGetPackageInfo(string srcRepo, string packageName, stri
var lowerSrcRepo = component.SrcRepoName.ToLower();
var lowerPackageName = component.JfrogPackageName.ToLower();
var lowerPath = component.Path.ToLower();


packageInfo = await TryGetPackageInfo(lowerSrcRepo, lowerPackageName, lowerPath);
packageInfo = await TryGetPackageInfo(component);

if (packageInfo != null)
{
component.CopyPackageApiUrl = component.CopyPackageApiUrl.ToLower();
}
}

// Retry with wildcard path if still not found
// ToDo - A better way would need to be thought of in the future.
if (packageInfo == null)
{
packageInfo = await TryGetPackageInfo(component.SrcRepoName, component.JfrogPackageName, $"{component.Path}*");

if (packageInfo != null)
{
// Build URLs
string BuildUrl(string apiConstant) =>
$"{component.JfrogApi}{apiConstant}{component.SrcRepoName}/{packageInfo.Path}/{packageInfo.Name}" +
$"?to=/{component.DestRepoName}/{packageInfo.Path}/{packageInfo.Name}";

component.CopyPackageApiUrl = component.DryRun ? $"{BuildUrl(ApiConstant.CopyPackageApi)}&dry=1" : BuildUrl(ApiConstant.CopyPackageApi);
component.MovePackageApiUrl = component.DryRun ? $"{BuildUrl(ApiConstant.MovePackageApi)}&dry=1" : BuildUrl(ApiConstant.MovePackageApi);
}
}
}

return packageInfo;
}
Expand Down
Loading

0 comments on commit 11bcece

Please sign in to comment.