From 5cf4d6f8fc55e7047fc155dc70bb152be2aece58 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Wed, 15 Oct 2025 19:56:16 +0530 Subject: [PATCH 1/2] Updating test data and dependency for jf rbs command --- go.mod | 2 +- go.sum | 4 +- lifecycle_test.go | 297 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 300 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6b5bb6ec9..f1b449a4f 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( github.com/jfrog/build-info-go v1.12.0 github.com/jfrog/gofrog v1.7.6 github.com/jfrog/jfrog-cli-application v1.0.1 - github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251015051724-72d111a3d107 + github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251015052652-84ea3afaf439 github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251015045218-1a38c9e47097 github.com/jfrog/jfrog-cli-platform-services v1.10.0 github.com/jfrog/jfrog-cli-security v1.21.8 diff --git a/go.sum b/go.sum index c1c1d9ea6..4637bff81 100644 --- a/go.sum +++ b/go.sum @@ -365,8 +365,8 @@ github.com/jfrog/jfrog-apps-config v1.0.1 h1:mtv6k7g8A8BVhlHGlSveapqf4mJfonwvXYL github.com/jfrog/jfrog-apps-config v1.0.1/go.mod h1:8AIIr1oY9JuH5dylz2S6f8Ym2MaadPLR6noCBO4C22w= github.com/jfrog/jfrog-cli-application v1.0.1 h1:PiiSVKFFs8VLAwjCe2JrIKlX7LmARFt+r8BLTupWIDc= github.com/jfrog/jfrog-cli-application v1.0.1/go.mod h1:gjV6Q2hhoMe3FF77GFiTyIRLSHokpDrkVj0GvYM+1Y4= -github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251015051724-72d111a3d107 h1:0VVFI1AHzMKyr/Nwxmu/Jhg3U1Rq725AQPKpSTtk7XU= -github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251015051724-72d111a3d107/go.mod h1:nT050Wb18tTlfcQHefyMENzFOz9Vdym6WP0Z3Nc2qHc= +github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251015052652-84ea3afaf439 h1:3B3JGujNYFpHQ69pjaPpRf0Ugny0UCU35whkcmGqaHc= +github.com/jfrog/jfrog-cli-artifactory v0.7.3-0.20251015052652-84ea3afaf439/go.mod h1:nT050Wb18tTlfcQHefyMENzFOz9Vdym6WP0Z3Nc2qHc= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251015045218-1a38c9e47097 h1:+W6BPxJ0nPtlQ6l6nmypW1eEANoVPiN8HDR4kQJA8uI= github.com/jfrog/jfrog-cli-core/v2 v2.60.1-0.20251015045218-1a38c9e47097/go.mod h1:UOeOwEEmRIi57cRwghN5OBVoqkJieYQQfLpeqw8Yv38= github.com/jfrog/jfrog-cli-platform-services v1.10.0 h1:O+N/VAF+QjFvq9xkHpmzKLcdl9aJu3IP204Su0L14rw= diff --git a/lifecycle_test.go b/lifecycle_test.go index 841e01b0d..57ee9fc1d 100644 --- a/lifecycle_test.go +++ b/lifecycle_test.go @@ -7,6 +7,7 @@ import ( "os" "path" "path/filepath" + "sort" "strconv" "strings" "testing" @@ -749,6 +750,302 @@ func deleteReleaseBundleProperties(t *testing.T, lcManager *lifecycle.LifecycleS time.Sleep(5 * time.Second) } +func createRbIfDoesNotExists(t *testing.T, specName, rbName, rbVersion string, lcManager *lifecycle.LifecycleServicesManager) { + isExist, err := lcManager.IsReleaseBundleExist(rbName, rbVersion, "") + assert.NoError(t, err) + if isExist { + return + } + createRbFromSpec(t, specName, rbName, rbVersion, true, true) +} + +func TestReleaseBundlesSearchGroups(t *testing.T) { + cleanCallback := initLifecycleTest(t, artifactoryLifecycleSetTagMinVersion) + defer cleanCallback() + + lcManager := getLcServiceManager(t) + + deleteBuilds := uploadBuilds(t) + defer deleteBuilds() + + const rbPrefix = "my-awesome-app" + const rbNameA = rbPrefix + "-alpha" + const rbNameB = rbPrefix + "-beta" + const rbNameC = rbPrefix + "-core" + const rbNameD = "another-app" + + const version1 = "1.0.0" + + // Create Release Bundle A + createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbNameA, version1, lcManager) + defer deleteReleaseBundle(t, lcManager, rbNameA, version1) + assertStatusCompleted(t, lcManager, rbNameA, version1, "") + + // Create Release Bundle B + createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbNameB, version1, lcManager) + defer deleteReleaseBundle(t, lcManager, rbNameB, version1) + assertStatusCompleted(t, lcManager, rbNameB, version1, "") + + // Create Release Bundle C + createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbNameC, version1, lcManager) + defer deleteReleaseBundle(t, lcManager, rbNameC, version1) + assertStatusCompleted(t, lcManager, rbNameC, version1, "") + + // Create Release Bundle D (for filter/exclusion) + createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbNameD, version1, lcManager) + defer deleteReleaseBundle(t, lcManager, rbNameD, version1) + assertStatusCompleted(t, lcManager, rbNameD, version1, "") + + time.Sleep(3 * time.Second) + + testCases := []struct { + name string + queryParams services.GetSearchOptionalQueryParams + expectedRbNames []string + expectedTotal int + expectError bool + errorMessage string + }{ + { + name: "No query params - all groups, default order", + queryParams: services.GetSearchOptionalQueryParams{}, + expectedRbNames: []string{rbNameD, rbNameC, rbNameB, rbNameA}, + expectedTotal: 4, + expectError: false, + }, + { + name: "Filter by prefix 'my-awesome-app'", + queryParams: services.GetSearchOptionalQueryParams{ + FilterBy: rbPrefix + "*", + }, + expectedRbNames: []string{rbNameC, rbNameB, rbNameA}, + expectedTotal: 3, + expectError: false, + }, + { + name: "Filter by containing 'beta'", + queryParams: services.GetSearchOptionalQueryParams{ + FilterBy: rbPrefix + "-beta", + }, + expectedRbNames: []string{rbNameB}, + expectedTotal: 1, + expectError: false, + }, + { + name: "Limit to 2 results", + queryParams: services.GetSearchOptionalQueryParams{ + Limit: 2, + }, + expectedTotal: 2, + expectError: false, + }, + { + name: "Offset by 1, Limit to 2 results", + queryParams: services.GetSearchOptionalQueryParams{ + Offset: 1, + Limit: 2, + }, + expectedTotal: 2, + expectError: false, + }, + { + name: "Order by name Descending", + queryParams: services.GetSearchOptionalQueryParams{ + OrderBy: "created", + OrderAsc: false, + }, + expectedRbNames: []string{rbNameD, rbNameC, rbNameB, rbNameA}, + expectedTotal: 4, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resp, err := lcManager.ReleaseBundlesSearchGroup(tc.queryParams) + if tc.expectError { + assert.Error(t, err) + if tc.errorMessage != "" { + assert.Contains(t, err.Error(), tc.errorMessage) + } + return + } + assert.NoError(t, err, fmt.Sprintf("Expected no error for test case: %s", tc.name)) + if tc.queryParams.FilterBy != "" { + assert.Equal(t, tc.expectedTotal, len(resp.ReleaseBundleSearchGroup), "Total count mismatch for filtered search") + } else { + assert.GreaterOrEqual(t, resp.Total, tc.expectedTotal, "Total count should be at least expected for unfiltered search") + } + var actualNames []string + for _, rb := range resp.ReleaseBundleSearchGroup { + actualNames = append(actualNames, rb.ReleaseBundleName) + } + if tc.queryParams.FilterBy != "" { + assert.Equal(t, tc.expectedRbNames, actualNames, "Release bundle names order mismatch") + } else { + assert.Subset(t, actualNames, tc.expectedRbNames, "Actual names should contain all expected names") + } + }) + } +} + +func TestReleaseBundlesSearchVersions(t *testing.T) { + cleanCallback := initLifecycleTest(t, artifactoryLifecycleSetTagMinVersion) + defer cleanCallback() + + lcManager := getLcServiceManager(t) + + deleteBuilds := uploadBuilds(t) + defer deleteBuilds() + + const rbName = "my-versioned-app" + const versionA = "1.0.0" + const versionB = "1.0.1" + const versionC = "1.1.0-rc" + const versionD = "2.0.0" + + createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbName, versionA, lcManager) + defer deleteReleaseBundle(t, lcManager, rbName, versionA) + assertStatusCompleted(t, lcManager, rbName, versionA, "") + + time.Sleep(1 * time.Second) + + createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbName, versionB, lcManager) + defer deleteReleaseBundle(t, lcManager, rbName, versionB) + assertStatusCompleted(t, lcManager, rbName, versionB, "") + + time.Sleep(1 * time.Second) + + createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbName, versionC, lcManager) + defer deleteReleaseBundle(t, lcManager, rbName, versionC) + assertStatusCompleted(t, lcManager, rbName, versionC, "") + + time.Sleep(1 * time.Second) + + createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbName, versionD, lcManager) + defer deleteReleaseBundle(t, lcManager, rbName, versionD) + assertStatusCompleted(t, lcManager, rbName, versionD, "") + + log.Info("Created four versions for release bundle '%s' for search testing.", rbName) + time.Sleep(3 * time.Second) + + testCases := []struct { + name string + releaseBundleName string + queryParams services.GetSearchOptionalQueryParams + expectedRbVersions []string + expectedTotal int + expectError bool + errorMessage string + }{ + { + name: "No query params - all versions, default order", + releaseBundleName: rbName, + queryParams: services.GetSearchOptionalQueryParams{}, + expectedRbVersions: []string{versionA, versionB, versionC, versionD}, + expectedTotal: 4, + expectError: false, + }, + { + name: "Filter by prefix '1.0'", + releaseBundleName: rbName, + queryParams: services.GetSearchOptionalQueryParams{ + FilterBy: "1.0*", + }, + expectedRbVersions: []string{versionA, versionB}, + expectedTotal: 2, + expectError: false, + }, + { + name: "Filter by containing 'rc'", + releaseBundleName: rbName, + queryParams: services.GetSearchOptionalQueryParams{ + FilterBy: "1.1.0-rc*", + }, + expectedRbVersions: []string{versionC}, + expectedTotal: 1, + expectError: false, + }, + { + name: "Limit to 2 results, ordered by version ascending", + releaseBundleName: rbName, + queryParams: services.GetSearchOptionalQueryParams{ + Limit: 2, + OrderBy: "release_bundle_version", + OrderAsc: true, + }, + expectedRbVersions: []string{versionA, versionB}, + expectedTotal: 2, + expectError: false, + }, + { + name: "Offset by 2, Limit 1, ordered by version descending", + releaseBundleName: rbName, + queryParams: services.GetSearchOptionalQueryParams{ + Offset: 2, + Limit: 1, + OrderBy: "release_bundle_version", + OrderAsc: false, + }, + expectedRbVersions: []string{versionB}, + expectedTotal: 1, + expectError: false, + }, + { + name: "Order by version Descending", + releaseBundleName: rbName, + queryParams: services.GetSearchOptionalQueryParams{ + OrderBy: "release_bundle_version", + OrderAsc: false, + }, + expectedRbVersions: []string{versionD, versionC, versionB, versionA}, + expectedTotal: 4, + expectError: false, + }, + { + name: "Order by created Ascending", + releaseBundleName: rbName, + queryParams: services.GetSearchOptionalQueryParams{ + OrderBy: "created", + OrderAsc: true, + }, + expectedRbVersions: []string{versionA, versionC, versionB, versionD}, + expectedTotal: 4, + expectError: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + var resp services.ReleaseBundleVersionsResponse + var err error + resp, err = lcManager.ReleaseBundlesSearchVersions(tc.releaseBundleName, tc.queryParams) + if tc.expectError { + assert.Error(t, err) + if tc.errorMessage != "" { + assert.Contains(t, err.Error(), tc.errorMessage) + } + return + } + if tc.queryParams.FilterBy != "" { + assert.Equal(t, tc.expectedTotal, len(resp.ReleaseBundles), "Total count mismatch for filtered search") + } else { + assert.GreaterOrEqual(t, resp.Total, tc.expectedTotal, "Total count should be at least expected for unfiltered search") + } + var actualVersions []string + for _, rb := range resp.ReleaseBundles { + actualVersions = append(actualVersions, rb.ReleaseBundleVersion) + } + if tc.queryParams.FilterBy != "" { + sort.Strings(actualVersions) + assert.Equal(t, tc.expectedRbVersions, actualVersions, "Release bundle versions order mismatch") + } else { + assert.Subset(t, actualVersions, tc.expectedRbVersions, "Actual names should contain all expected names") + } + }) + } +} + func setReleaseBundleTag(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion, projectKey, tag string, ) { From 337be41e2527af320e280536d2f30a1df651bd89 Mon Sep 17 00:00:00 2001 From: Naveen Kumar Date: Wed, 15 Oct 2025 20:01:49 +0530 Subject: [PATCH 2/2] Removing lint errors --- lifecycle_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lifecycle_test.go b/lifecycle_test.go index 57ee9fc1d..8f2d37213 100644 --- a/lifecycle_test.go +++ b/lifecycle_test.go @@ -750,13 +750,13 @@ func deleteReleaseBundleProperties(t *testing.T, lcManager *lifecycle.LifecycleS time.Sleep(5 * time.Second) } -func createRbIfDoesNotExists(t *testing.T, specName, rbName, rbVersion string, lcManager *lifecycle.LifecycleServicesManager) { +func createRbIfDoesNotExists(t *testing.T, rbName, rbVersion string, lcManager *lifecycle.LifecycleServicesManager) { isExist, err := lcManager.IsReleaseBundleExist(rbName, rbVersion, "") assert.NoError(t, err) if isExist { return } - createRbFromSpec(t, specName, rbName, rbVersion, true, true) + createRbFromSpec(t, tests.LifecycleBuilds12, rbName, rbVersion, true, true) } func TestReleaseBundlesSearchGroups(t *testing.T) { @@ -777,22 +777,22 @@ func TestReleaseBundlesSearchGroups(t *testing.T) { const version1 = "1.0.0" // Create Release Bundle A - createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbNameA, version1, lcManager) + createRbIfDoesNotExists(t, rbNameA, version1, lcManager) defer deleteReleaseBundle(t, lcManager, rbNameA, version1) assertStatusCompleted(t, lcManager, rbNameA, version1, "") // Create Release Bundle B - createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbNameB, version1, lcManager) + createRbIfDoesNotExists(t, rbNameB, version1, lcManager) defer deleteReleaseBundle(t, lcManager, rbNameB, version1) assertStatusCompleted(t, lcManager, rbNameB, version1, "") // Create Release Bundle C - createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbNameC, version1, lcManager) + createRbIfDoesNotExists(t, rbNameC, version1, lcManager) defer deleteReleaseBundle(t, lcManager, rbNameC, version1) assertStatusCompleted(t, lcManager, rbNameC, version1, "") // Create Release Bundle D (for filter/exclusion) - createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbNameD, version1, lcManager) + createRbIfDoesNotExists(t, rbNameD, version1, lcManager) defer deleteReleaseBundle(t, lcManager, rbNameD, version1) assertStatusCompleted(t, lcManager, rbNameD, version1, "") @@ -904,25 +904,25 @@ func TestReleaseBundlesSearchVersions(t *testing.T) { const versionC = "1.1.0-rc" const versionD = "2.0.0" - createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbName, versionA, lcManager) + createRbIfDoesNotExists(t, rbName, versionA, lcManager) defer deleteReleaseBundle(t, lcManager, rbName, versionA) assertStatusCompleted(t, lcManager, rbName, versionA, "") time.Sleep(1 * time.Second) - createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbName, versionB, lcManager) + createRbIfDoesNotExists(t, rbName, versionB, lcManager) defer deleteReleaseBundle(t, lcManager, rbName, versionB) assertStatusCompleted(t, lcManager, rbName, versionB, "") time.Sleep(1 * time.Second) - createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbName, versionC, lcManager) + createRbIfDoesNotExists(t, rbName, versionC, lcManager) defer deleteReleaseBundle(t, lcManager, rbName, versionC) assertStatusCompleted(t, lcManager, rbName, versionC, "") time.Sleep(1 * time.Second) - createRbIfDoesNotExists(t, tests.LifecycleBuilds12, rbName, versionD, lcManager) + createRbIfDoesNotExists(t, rbName, versionD, lcManager) defer deleteReleaseBundle(t, lcManager, rbName, versionD) assertStatusCompleted(t, lcManager, rbName, versionD, "")