From 3ad0bd4b66edc43c167a1cf6fc89ca662dc75837 Mon Sep 17 00:00:00 2001 From: Reshmi Date: Mon, 29 Sep 2025 13:03:46 +0530 Subject: [PATCH 1/3] add tests for twine cmd to test props set or not --- go.mod | 1 + go.sum | 4 +- pip_test.go | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 239 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index a54125431..601623672 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.24.6 replace ( // Should not be updated to 0.2.6 due to a bug (https://github.com/jfrog/jfrog-cli-core/pull/372) github.com/c-bata/go-prompt => github.com/c-bata/go-prompt v0.2.5 + github.com/jfrog/jfrog-cli-artifactory => github.com/reshmifrog/jfrog-cli-artifactory v0.0.0-20250926092928-8101c4eead07 // Should not be updated to 0.2.0-beta.2 due to a bug (https://github.com/jfrog/jfrog-cli-core/pull/372) github.com/pkg/term => github.com/pkg/term v1.1.0 diff --git a/go.sum b/go.sum index 6f060d5f5..105bb5580 100644 --- a/go.sum +++ b/go.sum @@ -361,8 +361,6 @@ github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s= github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4= github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY= github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= -github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20250924123948-4fce9d68fabe h1:RTOKkKrAjAn/bV5phpCUgOJY+4LHLpjK1YdwpBSTwGs= -github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20250924123948-4fce9d68fabe/go.mod h1:N1nn6tNbyAjtdhLp89tO1CstT+iWcQSzAJGvAml7Deg= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20250925124759-72e2205de3f6 h1:BA6o4MYduG3IxZbSxqIQQ7maTjUszgK3YOXQrZdP/Rk= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20250925124759-72e2205de3f6/go.mod h1:Z1nBKbz0ZOZrOIS9maGp5LZpHaxuufZAABVF+DAz9wo= github.com/jfrog/jfrog-cli-platform-services v1.10.0 h1:O+N/VAF+QjFvq9xkHpmzKLcdl9aJu3IP204Su0L14rw= @@ -518,6 +516,8 @@ github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2 github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= +github.com/reshmifrog/jfrog-cli-artifactory v0.0.0-20250926092928-8101c4eead07 h1:bTWAa6xQHlCEeFuLdDCqk0oIlWr5HavakCWU+mGNomY= +github.com/reshmifrog/jfrog-cli-artifactory v0.0.0-20250926092928-8101c4eead07/go.mod h1:N1nn6tNbyAjtdhLp89tO1CstT+iWcQSzAJGvAml7Deg= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= diff --git a/pip_test.go b/pip_test.go index 23ca2d55f..9a97a1567 100644 --- a/pip_test.go +++ b/pip_test.go @@ -8,8 +8,11 @@ import ( "os/exec" "path/filepath" "strconv" + "strings" "testing" + "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" + biutils "github.com/jfrog/build-info-go/utils" "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" coretests "github.com/jfrog/jfrog-cli-core/v2/utils/tests" @@ -369,6 +372,239 @@ func testTwineCmd(t *testing.T, projectPath, buildNumber, expectedModuleId strin assert.Equal(t, expectedModuleId, twineModule.Id) } +func TestTwineWithBuildNameAndNumberProperties(t *testing.T) { + if !*tests.TestPip { + t.Skip("Skipping test. Requires '-test.pip=true' options.") + } + initPipTest(t) + + oldHomeDir, newHomeDir := prepareHomeDir(t) + defer func() { + clientTestUtils.SetEnvAndAssert(t, coreutils.HomeDir, oldHomeDir) + clientTestUtils.RemoveAllAndAssert(t, newHomeDir) + }() + + allTests := []struct { + name string + project string + outputFolder string + expectedModuleId string + args []string + expectedArtifacts int + }{ + {"twineWithProbs", "pyproject", "twine", "jfrog-python-example:1.0", []string{}, 2}, + } + + for testNumber, test := range allTests { + t.Run(test.name, func(t *testing.T) { + cleanVirtualEnv, err := prepareVirtualEnv(t) + assert.NoError(t, err) + + buildNumber := strconv.Itoa(100 + testNumber) + test.args = append([]string{"twine", "upload", "dist/*", "--build-name=" + tests.PipBuildName, "--build-number=" + buildNumber}, test.args...) + VerifyBuildNameAndNumberPropertiesOnTwineArtifact(t, createPypiProject(t, test.outputFolder, test.project, "twine"), buildNumber, test.expectedModuleId, test.expectedArtifacts, test.args) + + cleanVirtualEnv() + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, tests.PipBuildName, artHttpDetails) + }) + } +} + +func VerifyBuildNameAndNumberPropertiesOnTwineArtifact(t *testing.T, projectPath, buildNumber, expectedModuleId string, expectedArtifacts int, args []string) { + wd, err := os.Getwd() + assert.NoError(t, err, "Failed to get current dir") + chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, projectPath) + defer chdirCallback() + + jfrogCli := coretests.NewJfrogCli(execMain, "jfrog", "") + err = jfrogCli.Exec(args...) + if err != nil { + assert.Fail(t, "Failed executing twine upload command", err.Error()) + return + } + + assert.NoError(t, artifactoryCli.Exec("bp", tests.PipBuildName, buildNumber)) + + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, tests.PipBuildName, buildNumber) + if err != nil { + assert.NoError(t, err) + return + } + if !found { + assert.True(t, found, "build info was expected to be found") + return + } + buildInfo := publishedBuildInfo.BuildInfo + require.Len(t, buildInfo.Modules, 1) + twineModule := buildInfo.Modules[0] + assert.Equal(t, buildinfo.Python, twineModule.Type) + assert.Len(t, twineModule.Artifacts, expectedArtifacts) + assert.Equal(t, expectedModuleId, twineModule.Id) + + serviceManager, err := utils.CreateServiceManager(serverDetails, 3, 1000, false) + if err != nil { + return + } + + for _, artifact := range twineModule.Artifacts { + relativePath := artifact.OriginalDeploymentRepo + "/" + artifact.Path + + probs, err := serviceManager.GetItemProps(relativePath) + if err != nil { + assert.Fail(t, "Failed to get item properties for the twine module artifact", err.Error()) + continue + } + + if probs == nil { + assert.Fail(t, "Properties for the twine module artifact are not set") + continue + } + + buildNameProp, exists := probs.Properties["build.name"] + assert.True(t, exists, "build.name property not found for artifact: "+artifact.Name) + if exists { + assert.Contains(t, buildNameProp, tests.PipBuildName, "build.name property does not match expected value") + } + + buildNumberProp, exists := probs.Properties["build.number"] + assert.True(t, exists, "build.number property not found for artifact: "+artifact.Name) + if exists { + assert.Contains(t, buildNumberProp, buildNumber, "build.number property does not match expected value") + } + + buildTimestampProp, exists := probs.Properties["build.timestamp"] + assert.True(t, exists, "build.timestamp property not found for artifact: "+artifact.Name) + if exists { + assert.NotEmpty(t, buildTimestampProp, "build.timestamp property is empty for artifact: "+artifact.Name) + if len(buildTimestampProp) > 0 { + timestampStr := buildTimestampProp[0] + _, err := strconv.ParseInt(timestampStr, 10, 64) + assert.NoError(t, err, "build.timestamp is not a valid timestamp number: "+timestampStr) + } + } + } +} + +func TestTwineAndGenericUploadSameBuildInfo(t *testing.T) { + if !*tests.TestArtifactory || !*tests.TestPip { + t.Skip("Skipping test. Requires both '-test.artifactory=true' and '-test.pip=true' options.") + } + + oldHomeDir, newHomeDir := prepareHomeDir(t) + defer func() { + clientTestUtils.SetEnvAndAssert(t, coreutils.HomeDir, oldHomeDir) + clientTestUtils.RemoveAllAndAssert(t, newHomeDir) + }() + + cleanVirtualEnv, err := prepareVirtualEnv(t) + assert.NoError(t, err) + defer cleanVirtualEnv() + + projectPath := createPypiProject(t, "twine-generic-test", "pyproject", "twine") + wd, err := os.Getwd() + assert.NoError(t, err, "Failed to get current dir") + chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, projectPath) + defer chdirCallback() + + buildName := "test-twine-generic-build" + buildNumber := "1" + + jfrogCli := coretests.NewJfrogCli(execMain, "jfrog", "") + twineArgs := []string{"twine", "upload", "dist/*", "--build-name=" + buildName, "--build-number=" + buildNumber} + err = jfrogCli.Exec(twineArgs...) + assert.NoError(t, err, "Failed executing twine upload command") + + chdirCallback() + + testFileName := "test-artifact.zip" + testFilePath := filepath.Join(t.TempDir(), testFileName) + err = os.WriteFile(testFilePath, []byte("test content for generic upload"), 0644) + assert.NoError(t, err) + + uploadArgs := []string{"upload", testFilePath, tests.RtRepo1 + "/", "--build-name=" + buildName, "--build-number=" + buildNumber} + err = artifactoryCli.Exec(uploadArgs...) + assert.NoError(t, err, "Failed executing generic upload command") + + err = artifactoryCli.Exec("bp", buildName, buildNumber) + assert.NoError(t, err, "Failed publishing build info") + + publishedBuildInfo, found, err := tests.GetBuildInfo(serverDetails, buildName, buildNumber) + assert.NoError(t, err) + assert.True(t, found, "build info was expected to be found") + + buildInfo := publishedBuildInfo.BuildInfo + + require.Len(t, buildInfo.Modules, 2, "Expected 2 modules in build info") + + serviceManager, err := utils.CreateServiceManager(serverDetails, 3, 1000, false) + assert.NoError(t, err) + + var missingPropsErrors []string + + for _, module := range buildInfo.Modules { + for _, artifact := range module.Artifacts { + relativePath := artifact.OriginalDeploymentRepo + "/" + artifact.Path + probs, err := serviceManager.GetItemProps(relativePath) + if err != nil { + missingPropsErrors = append(missingPropsErrors, + fmt.Sprintf("Failed to get properties for %s artifact '%s': %v", module.Type, artifact.Name, err)) + continue + } + + if probs == nil { + missingPropsErrors = append(missingPropsErrors, + fmt.Sprintf("Properties are nil for %s artifact '%s'", module.Type, artifact.Name)) + continue + } + + buildNameProp, exists := probs.Properties["build.name"] + if !exists { + missingPropsErrors = append(missingPropsErrors, + fmt.Sprintf("Missing build.name property for %s artifact '%s'", module.Type, artifact.Name)) + } else if !contains(buildNameProp, buildName) { + missingPropsErrors = append(missingPropsErrors, + fmt.Sprintf("Incorrect build.name for %s artifact '%s': expected %s, got %v", + module.Type, artifact.Name, buildName, buildNameProp)) + } + + buildNumberProp, exists := probs.Properties["build.number"] + if !exists { + missingPropsErrors = append(missingPropsErrors, + fmt.Sprintf("Missing build.number property for %s artifact '%s'", module.Type, artifact.Name)) + } else if !contains(buildNumberProp, buildNumber) { + missingPropsErrors = append(missingPropsErrors, + fmt.Sprintf("Incorrect build.number for %s artifact '%s': expected %s, got %v", + module.Type, artifact.Name, buildNumber, buildNumberProp)) + } + + buildTimestampProp, exists := probs.Properties["build.timestamp"] + if !exists { + missingPropsErrors = append(missingPropsErrors, + fmt.Sprintf("Missing build.timestamp property for %s artifact '%s'", + module.Type, artifact.Name)) + } else if len(buildTimestampProp) == 0 || buildTimestampProp[0] == "" { + missingPropsErrors = append(missingPropsErrors, + fmt.Sprintf("Empty build.timestamp property for %s artifact '%s'", module.Type, artifact.Name)) + } else { + timestampStr := buildTimestampProp[0] + _, err := strconv.ParseInt(timestampStr, 10, 64) + if err != nil { + missingPropsErrors = append(missingPropsErrors, + fmt.Sprintf("Invalid build.timestamp format for %s artifact '%s': %s", + module.Type, artifact.Name, timestampStr)) + } + } + } + } + + if len(missingPropsErrors) > 0 { + errMsg := "missing build properties for the artifacts: \n" + strings.Join(missingPropsErrors, "\n") + assert.Fail(t, errMsg) + } + + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) +} + func TestSetupPipCommand(t *testing.T) { if !*tests.TestPip { t.Skip("Skipping Pip test. To run Pip test add the '-test.pip=true' option.") From b2de799c7a1a803cc2d3ebcc3e4ce307f194854e Mon Sep 17 00:00:00 2001 From: Reshmi Date: Mon, 29 Sep 2025 16:56:16 +0530 Subject: [PATCH 2/3] renamed test funtion, separate method for validating props --- pip_test.go | 174 +++++++++++++++++++++++++--------------------------- 1 file changed, 82 insertions(+), 92 deletions(-) diff --git a/pip_test.go b/pip_test.go index 9a97a1567..a59a6b000 100644 --- a/pip_test.go +++ b/pip_test.go @@ -17,6 +17,7 @@ import ( "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" coretests "github.com/jfrog/jfrog-cli-core/v2/utils/tests" "github.com/jfrog/jfrog-cli-security/sca/bom/buildinfo/technologies/python" + "github.com/jfrog/jfrog-client-go/artifactory" "github.com/jfrog/jfrog-client-go/http/httpclient" clientTestUtils "github.com/jfrog/jfrog-client-go/utils/tests" @@ -372,7 +373,7 @@ func testTwineCmd(t *testing.T, projectPath, buildNumber, expectedModuleId strin assert.Equal(t, expectedModuleId, twineModule.Id) } -func TestTwineWithBuildNameAndNumberProperties(t *testing.T) { +func TestTwineWithBuildNameAndNumberAndTimeStampProperties(t *testing.T) { if !*tests.TestPip { t.Skip("Skipping test. Requires '-test.pip=true' options.") } @@ -392,7 +393,7 @@ func TestTwineWithBuildNameAndNumberProperties(t *testing.T) { args []string expectedArtifacts int }{ - {"twineWithProbs", "pyproject", "twine", "jfrog-python-example:1.0", []string{}, 2}, + {"twineWithProps", "pyproject", "twine", "jfrog-python-example:1.0", []string{}, 2}, } for testNumber, test := range allTests { @@ -402,7 +403,7 @@ func TestTwineWithBuildNameAndNumberProperties(t *testing.T) { buildNumber := strconv.Itoa(100 + testNumber) test.args = append([]string{"twine", "upload", "dist/*", "--build-name=" + tests.PipBuildName, "--build-number=" + buildNumber}, test.args...) - VerifyBuildNameAndNumberPropertiesOnTwineArtifact(t, createPypiProject(t, test.outputFolder, test.project, "twine"), buildNumber, test.expectedModuleId, test.expectedArtifacts, test.args) + verifyBuildNameNumberTimestampPropertiesOnTwineArtifact(t, createPypiProject(t, test.outputFolder, test.project, "twine"), buildNumber, test.expectedModuleId, test.expectedArtifacts, test.args) cleanVirtualEnv() inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, tests.PipBuildName, artHttpDetails) @@ -410,7 +411,7 @@ func TestTwineWithBuildNameAndNumberProperties(t *testing.T) { } } -func VerifyBuildNameAndNumberPropertiesOnTwineArtifact(t *testing.T, projectPath, buildNumber, expectedModuleId string, expectedArtifacts int, args []string) { +func verifyBuildNameNumberTimestampPropertiesOnTwineArtifact(t *testing.T, projectPath, buildNumber, expectedModuleId string, expectedArtifacts int, args []string) { wd, err := os.Getwd() assert.NoError(t, err, "Failed to get current dir") chdirCallback := clientTestUtils.ChangeDirWithCallback(t, wd, projectPath) @@ -446,42 +447,14 @@ func VerifyBuildNameAndNumberPropertiesOnTwineArtifact(t *testing.T, projectPath return } + var allErrors []string for _, artifact := range twineModule.Artifacts { - relativePath := artifact.OriginalDeploymentRepo + "/" + artifact.Path - - probs, err := serviceManager.GetItemProps(relativePath) - if err != nil { - assert.Fail(t, "Failed to get item properties for the twine module artifact", err.Error()) - continue - } - - if probs == nil { - assert.Fail(t, "Properties for the twine module artifact are not set") - continue - } - - buildNameProp, exists := probs.Properties["build.name"] - assert.True(t, exists, "build.name property not found for artifact: "+artifact.Name) - if exists { - assert.Contains(t, buildNameProp, tests.PipBuildName, "build.name property does not match expected value") - } - - buildNumberProp, exists := probs.Properties["build.number"] - assert.True(t, exists, "build.number property not found for artifact: "+artifact.Name) - if exists { - assert.Contains(t, buildNumberProp, buildNumber, "build.number property does not match expected value") - } + errors := verifyBuildProperties(serviceManager, artifact, buildinfo.Python, tests.PipBuildName, buildNumber) + allErrors = append(allErrors, errors...) + } - buildTimestampProp, exists := probs.Properties["build.timestamp"] - assert.True(t, exists, "build.timestamp property not found for artifact: "+artifact.Name) - if exists { - assert.NotEmpty(t, buildTimestampProp, "build.timestamp property is empty for artifact: "+artifact.Name) - if len(buildTimestampProp) > 0 { - timestampStr := buildTimestampProp[0] - _, err := strconv.ParseInt(timestampStr, 10, 64) - assert.NoError(t, err, "build.timestamp is not a valid timestamp number: "+timestampStr) - } - } + if len(allErrors) > 0 { + assert.Fail(t, "Missing build properties for the artifacts:\n"+strings.Join(allErrors, "\n")) } } @@ -539,70 +512,87 @@ func TestTwineAndGenericUploadSameBuildInfo(t *testing.T) { serviceManager, err := utils.CreateServiceManager(serverDetails, 3, 1000, false) assert.NoError(t, err) - var missingPropsErrors []string - + var allErrors []string for _, module := range buildInfo.Modules { for _, artifact := range module.Artifacts { - relativePath := artifact.OriginalDeploymentRepo + "/" + artifact.Path - probs, err := serviceManager.GetItemProps(relativePath) - if err != nil { - missingPropsErrors = append(missingPropsErrors, - fmt.Sprintf("Failed to get properties for %s artifact '%s': %v", module.Type, artifact.Name, err)) - continue - } + errors := verifyBuildProperties(serviceManager, artifact, module.Type, buildName, buildNumber) + allErrors = append(allErrors, errors...) + } + } - if probs == nil { - missingPropsErrors = append(missingPropsErrors, - fmt.Sprintf("Properties are nil for %s artifact '%s'", module.Type, artifact.Name)) - continue - } + if len(allErrors) > 0 { + assert.Fail(t, "Missing build properties for the artifacts:\n"+strings.Join(allErrors, "\n")) + } - buildNameProp, exists := probs.Properties["build.name"] - if !exists { - missingPropsErrors = append(missingPropsErrors, - fmt.Sprintf("Missing build.name property for %s artifact '%s'", module.Type, artifact.Name)) - } else if !contains(buildNameProp, buildName) { - missingPropsErrors = append(missingPropsErrors, - fmt.Sprintf("Incorrect build.name for %s artifact '%s': expected %s, got %v", - module.Type, artifact.Name, buildName, buildNameProp)) - } + inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) +} - buildNumberProp, exists := probs.Properties["build.number"] - if !exists { - missingPropsErrors = append(missingPropsErrors, - fmt.Sprintf("Missing build.number property for %s artifact '%s'", module.Type, artifact.Name)) - } else if !contains(buildNumberProp, buildNumber) { - missingPropsErrors = append(missingPropsErrors, - fmt.Sprintf("Incorrect build.number for %s artifact '%s': expected %s, got %v", - module.Type, artifact.Name, buildNumber, buildNumberProp)) - } +func verifyBuildProperties(serviceManager artifactory.ArtifactoryServicesManager, artifact buildinfo.Artifact, + moduleType buildinfo.ModuleType, expectedBuildName, expectedBuildNumber string) []string { - buildTimestampProp, exists := probs.Properties["build.timestamp"] - if !exists { - missingPropsErrors = append(missingPropsErrors, - fmt.Sprintf("Missing build.timestamp property for %s artifact '%s'", - module.Type, artifact.Name)) - } else if len(buildTimestampProp) == 0 || buildTimestampProp[0] == "" { - missingPropsErrors = append(missingPropsErrors, - fmt.Sprintf("Empty build.timestamp property for %s artifact '%s'", module.Type, artifact.Name)) - } else { - timestampStr := buildTimestampProp[0] - _, err := strconv.ParseInt(timestampStr, 10, 64) - if err != nil { - missingPropsErrors = append(missingPropsErrors, - fmt.Sprintf("Invalid build.timestamp format for %s artifact '%s': %s", - module.Type, artifact.Name, timestampStr)) - } - } - } + var errors []string + + relativePath := artifact.OriginalDeploymentRepo + "/" + artifact.Path + props, err := serviceManager.GetItemProps(relativePath) + if err != nil { + return []string{fmt.Sprintf("Failed to get properties for %s artifact '%s': %v", + moduleType, artifact.Name, err)} } - if len(missingPropsErrors) > 0 { - errMsg := "missing build properties for the artifacts: \n" + strings.Join(missingPropsErrors, "\n") - assert.Fail(t, errMsg) + if props == nil { + return []string{fmt.Sprintf("Properties are nil for %s artifact '%s'", + moduleType, artifact.Name)} } - inttestutils.DeleteBuild(serverDetails.ArtifactoryUrl, buildName, artHttpDetails) + errors = append(errors, validateBuildNameProperty(props.Properties, moduleType, artifact.Name, expectedBuildName)...) + errors = append(errors, validateBuildNumberProperty(props.Properties, moduleType, artifact.Name, expectedBuildNumber)...) + errors = append(errors, validateBuildTimestampProperty(props.Properties, moduleType, artifact.Name)...) + + return errors +} + +func validateBuildNameProperty(properties map[string][]string, moduleType buildinfo.ModuleType, artifactName, expectedBuildName string) []string { + buildNameProp, exists := properties["build.name"] + if !exists { + return []string{fmt.Sprintf("Missing build.name property for %s artifact '%s'", moduleType, artifactName)} + } + if !contains(buildNameProp, expectedBuildName) { + return []string{fmt.Sprintf("Incorrect build.name for %s artifact '%s': expected %s, got %v", + moduleType, artifactName, expectedBuildName, buildNameProp)} + } + return nil +} + +func validateBuildNumberProperty(properties map[string][]string, moduleType buildinfo.ModuleType, artifactName, expectedBuildNumber string) []string { + buildNumberProp, exists := properties["build.number"] + if !exists { + return []string{fmt.Sprintf("Missing build.number property for %s artifact '%s'", moduleType, artifactName)} + } + if !contains(buildNumberProp, expectedBuildNumber) { + return []string{fmt.Sprintf("Incorrect build.number for %s artifact '%s': expected %s, got %v", + moduleType, artifactName, expectedBuildNumber, buildNumberProp)} + } + return nil +} + +func validateBuildTimestampProperty(properties map[string][]string, moduleType buildinfo.ModuleType, artifactName string) []string { + buildTimestampProp, exists := properties["build.timestamp"] + if !exists { + return []string{fmt.Sprintf("Missing build.timestamp property for %s artifact '%s'", moduleType, artifactName)} + } + + if len(buildTimestampProp) == 0 || buildTimestampProp[0] == "" { + return []string{fmt.Sprintf("Empty build.timestamp property for %s artifact '%s'", moduleType, artifactName)} + } + + timestampStr := buildTimestampProp[0] + _, err := strconv.ParseInt(timestampStr, 10, 64) + if err != nil { + return []string{fmt.Sprintf("Invalid build.timestamp format for %s artifact '%s': %s", + moduleType, artifactName, timestampStr)} + } + + return nil } func TestSetupPipCommand(t *testing.T) { From fdbc4da440cd0afc6bb8358a0fd3b1c01353d0a2 Mon Sep 17 00:00:00 2001 From: Reshmi Date: Tue, 30 Sep 2025 12:25:10 +0530 Subject: [PATCH 3/3] updated dependencies --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 601623672..f10e08810 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.6 replace ( // Should not be updated to 0.2.6 due to a bug (https://github.com/jfrog/jfrog-cli-core/pull/372) github.com/c-bata/go-prompt => github.com/c-bata/go-prompt v0.2.5 - github.com/jfrog/jfrog-cli-artifactory => github.com/reshmifrog/jfrog-cli-artifactory v0.0.0-20250926092928-8101c4eead07 + github.com/jfrog/jfrog-cli-artifactory => github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20250930060931-d9c7efa90fbb // Should not be updated to 0.2.0-beta.2 due to a bug (https://github.com/jfrog/jfrog-cli-core/pull/372) github.com/pkg/term => github.com/pkg/term v1.1.0 diff --git a/go.sum b/go.sum index 105bb5580..41d8c9993 100644 --- a/go.sum +++ b/go.sum @@ -361,6 +361,8 @@ github.com/jfrog/gofrog v1.7.6 h1:QmfAiRzVyaI7JYGsB7cxfAJePAZTzFz0gRWZSE27c6s= github.com/jfrog/gofrog v1.7.6/go.mod h1:ntr1txqNOZtHplmaNd7rS4f8jpA5Apx8em70oYEe7+4= github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYLipdsOFMY= github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= +github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20250930060931-d9c7efa90fbb h1:wrl9zkkzfc2lFgEY+LhPbLK5quRX6/N8utq1WVdiM7I= +github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20250930060931-d9c7efa90fbb/go.mod h1:N1nn6tNbyAjtdhLp89tO1CstT+iWcQSzAJGvAml7Deg= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20250925124759-72e2205de3f6 h1:BA6o4MYduG3IxZbSxqIQQ7maTjUszgK3YOXQrZdP/Rk= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20250925124759-72e2205de3f6/go.mod h1:Z1nBKbz0ZOZrOIS9maGp5LZpHaxuufZAABVF+DAz9wo= github.com/jfrog/jfrog-cli-platform-services v1.10.0 h1:O+N/VAF+QjFvq9xkHpmzKLcdl9aJu3IP204Su0L14rw= @@ -516,8 +518,6 @@ github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2 github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= -github.com/reshmifrog/jfrog-cli-artifactory v0.0.0-20250926092928-8101c4eead07 h1:bTWAa6xQHlCEeFuLdDCqk0oIlWr5HavakCWU+mGNomY= -github.com/reshmifrog/jfrog-cli-artifactory v0.0.0-20250926092928-8101c4eead07/go.mod h1:N1nn6tNbyAjtdhLp89tO1CstT+iWcQSzAJGvAml7Deg= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=