@@ -26,6 +26,8 @@ import (
2626 "os"
2727 "path"
2828 "path/filepath"
29+ "strconv"
30+ "strings"
2931 "testing"
3032 "time"
3133)
@@ -45,6 +47,7 @@ const (
4547 artifactoryLifecycleSetTagMinVersion = "7.111.0"
4648 rbManifestName = "release-bundle.json.evd"
4749 releaseBundlesV2 = "release-bundles-v2"
50+ minMultiSourcesArtifactoryVersion = "7.114.0"
4851)
4952
5053var (
@@ -94,6 +97,89 @@ func compareRbArtifacts(t *testing.T, actual services.ReleaseBundleSpecResponse,
9497 assert .ElementsMatch (t , actualArtifactsPaths , expected )
9598}
9699
100+ func TestReleaseBundleCreationFromMultiBuildsUsingCommandFlag (t * testing.T ) {
101+
102+ cleanCallback := initLifecycleTest (t , minMultiSourcesArtifactoryVersion )
103+ defer cleanCallback ()
104+ lcManager := getLcServiceManager (t )
105+
106+ deleteBuilds := uploadBuilds (t )
107+ defer deleteBuilds ()
108+
109+ createRbFromMultiSourcesUsingCommandFlags (t , lcManager , createBuildsSource (), "" , tests .LcRbName1 , number1 , "default" , true )
110+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName1 , number1 )
111+ assertStatusCompleted (t , lcManager , tests .LcRbName1 , number1 , "" )
112+ }
113+
114+ func TestReleaseBundleCreationFromMultiBundlesUsingCommandFlag (t * testing.T ) {
115+
116+ cleanCallback := initLifecycleTest (t , minMultiSourcesArtifactoryVersion )
117+ defer cleanCallback ()
118+ lcManager := getLcServiceManager (t )
119+
120+ deleteBuilds := uploadBuilds (t )
121+ defer deleteBuilds ()
122+
123+ createRbFromSpec (t , tests .LifecycleBuilds12 , tests .LcRbName1 , number1 , true , true )
124+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName1 , number1 )
125+
126+ createRbFromSpec (t , tests .LifecycleBuilds3 , tests .LcRbName2 , number2 , true , true )
127+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName2 , number2 )
128+
129+ createRbFromMultiSourcesUsingCommandFlags (t , lcManager , "" , createReleaseBundlesSource (), tests .LcRbName3 , number3 , "default" , true )
130+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName3 , number3 )
131+ assertStatusCompleted (t , lcManager , tests .LcRbName3 , number3 , "" )
132+ }
133+
134+ func TestReleaseBundleCreationFromMultipleBuildsAndBundlesUsingCommandFlags (t * testing.T ) {
135+
136+ cleanCallback := initLifecycleTest (t , minMultiSourcesArtifactoryVersion )
137+ defer cleanCallback ()
138+ lcManager := getLcServiceManager (t )
139+
140+ deleteBuilds := uploadBuilds (t )
141+ defer deleteBuilds ()
142+
143+ createRbFromSpec (t , tests .LifecycleBuilds12 , tests .LcRbName1 , number1 , true , true )
144+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName1 , number1 )
145+
146+ createRbFromSpec (t , tests .LifecycleBuilds3 , tests .LcRbName2 , number2 , true , true )
147+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName2 , number2 )
148+
149+ createRbFromMultiSourcesUsingCommandFlags (t , lcManager , createBuildsSource (), createReleaseBundlesSource (), tests .LcRbName3 , number3 , "default" , true )
150+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName3 , number3 )
151+ assertStatusCompleted (t , lcManager , tests .LcRbName3 , number3 , "" )
152+ }
153+
154+ func TestReleaseBundleCreationFromMultipleSourcesUsingSpec (t * testing.T ) {
155+
156+ cleanCallback := initLifecycleTest (t , minMultiSourcesArtifactoryVersion )
157+ defer cleanCallback ()
158+ lcManager := getLcServiceManager (t )
159+
160+ deleteBuilds := uploadBuilds (t )
161+ defer deleteBuilds ()
162+
163+ createRbFromSpec (t , tests .LifecycleBuilds12 , tests .LcRbName1 , number1 , true , true )
164+
165+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName1 , number1 )
166+
167+ createRbFromSpec (t , tests .LifecycleBuilds3 , tests .LcRbName2 , number2 , true , true )
168+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName2 , number2 )
169+
170+ createRbFromSpec (t , tests .LifecycleMultipleSources , tests .LcRbName3 , number3 , true , true )
171+ defer deleteReleaseBundle (t , lcManager , tests .LcRbName3 , number3 )
172+ assertStatusCompleted (t , lcManager , tests .LcRbName3 , number3 , "" )
173+ }
174+
175+ func createReleaseBundlesSource () string {
176+ return fmt .Sprintf ("name=%s, version=%s; name=%s, version=%s" , tests .LcRbName1 , number1 , tests .LcRbName2 , number2 )
177+ }
178+
179+ func createBuildsSource () string {
180+ return fmt .Sprintf ("name=%s, id=%s, include-deps=%s; name=%s, id=%s" , tests .LcBuildName1 , number1 , "true" , tests .LcBuildName2 , number2 )
181+ }
182+
97183func TestReleaseBundleCreationFromAql (t * testing.T ) {
98184 testReleaseBundleCreation (t , tests .UploadDevSpecA , tests .LifecycleAql , tests .GetExpectedLifecycleCreationByAql (), false )
99185}
@@ -106,6 +192,120 @@ func TestReleaseBundleCreationFromArtifactsWithoutSigningKey(t *testing.T) {
106192 testReleaseBundleCreation (t , tests .UploadDevSpec , tests .LifecycleArtifacts , tests .GetExpectedLifecycleCreationByArtifacts (), withoutSigningKey )
107193}
108194
195+ func createRbFromMultiSourcesUsingCommandFlags (t * testing.T , lcManager * lifecycle.LifecycleServicesManager , buildsSourcesOption , bundlesSourcesOption ,
196+ rbName , rbVersion , project string , sync bool ) {
197+ var sources []services.RbSource
198+ sources = buildMultiSources (sources , buildsSourcesOption , bundlesSourcesOption , project )
199+
200+ rbDetails := services.ReleaseBundleDetails {
201+ ReleaseBundleName : rbName ,
202+ ReleaseBundleVersion : rbVersion ,
203+ }
204+ queryParams := services.CommonOptionalQueryParams {
205+ Async : ! sync ,
206+ ProjectKey : project ,
207+ }
208+
209+ _ , err := lcManager .CreateReleaseBundlesFromMultipleSources (rbDetails , queryParams , gpgKeyPairName , sources )
210+ assert .NoError (t , err )
211+ }
212+
213+ func buildMultiSources (sources []services.RbSource , buildsSourcesStr , bundlesSourcesStr , projectKey string ) []services.RbSource {
214+ // Process Builds
215+ if buildsSourcesStr != "" {
216+ sources = buildMultiBuildSources (sources , buildsSourcesStr )
217+ }
218+
219+ // Process Release Bundles
220+ if bundlesSourcesStr != "" {
221+ sources = buildMultiBundleSources (sources , bundlesSourcesStr , projectKey )
222+ }
223+
224+ return sources
225+ }
226+
227+ func buildMultiBundleSources (sources []services.RbSource , bundlesSourcesStr , projectKey string ) []services.RbSource {
228+ var releaseBundleSources []services.ReleaseBundleSource
229+ bundleEntries := strings .Split (bundlesSourcesStr , ";" )
230+ for _ , entry := range bundleEntries {
231+ entry = strings .TrimSpace (entry )
232+ if entry == "" {
233+ continue
234+ }
235+ // Assuming the format "name=xxx, version=xxx"
236+ components := strings .Split (entry , "," )
237+ if len (components ) != 2 {
238+ continue
239+ }
240+ name := strings .TrimSpace (strings .Split (components [0 ], "=" )[1 ])
241+ version := strings .TrimSpace (strings .Split (components [1 ], "=" )[1 ])
242+
243+ releaseBundleSources = append (releaseBundleSources , services.ReleaseBundleSource {
244+ ProjectKey : projectKey ,
245+ ReleaseBundleName : name ,
246+ ReleaseBundleVersion : version ,
247+ })
248+ }
249+ if len (releaseBundleSources ) > 0 {
250+ sources = append (sources , services.RbSource {
251+ SourceType : "release_bundles" ,
252+ ReleaseBundles : releaseBundleSources ,
253+ })
254+ }
255+ return sources
256+ }
257+
258+ func buildMultiBuildSources (sources []services.RbSource , sourcesStr string ) []services.RbSource {
259+ var buildSources []services.BuildSource
260+ buildEntries := strings .Split (sourcesStr , ";" )
261+ for _ , entry := range buildEntries {
262+ entry = strings .TrimSpace (entry )
263+ if entry == "" {
264+ continue
265+ }
266+ // Assuming the format "name=xxx, number=xxx, include-dep=true"
267+ components := strings .Split (entry , "," )
268+ if len (components ) < 2 {
269+ continue
270+ }
271+
272+ name := strings .TrimSpace (strings .Split (components [0 ], "=" )[1 ])
273+ number := strings .TrimSpace (strings .Split (components [1 ], "=" )[1 ])
274+
275+ includeDepStr := "false"
276+ if len (components ) >= 3 {
277+ parts := strings .Split (components [2 ], "=" )
278+ if len (parts ) > 1 {
279+ includeDepStr = strings .TrimSpace (parts [1 ])
280+ }
281+ }
282+
283+ includeDep , _ := strconv .ParseBool (includeDepStr )
284+
285+ buildSources = append (buildSources , services.BuildSource {
286+ BuildRepository : getBuildInfoRepositoryByProject ("default" ),
287+ BuildName : name ,
288+ BuildNumber : number ,
289+ IncludeDependencies : includeDep ,
290+ })
291+ }
292+ if len (buildSources ) > 0 {
293+ sources = append (sources , services.RbSource {
294+ SourceType : "builds" ,
295+ Builds : buildSources ,
296+ })
297+ }
298+ return sources
299+ }
300+
301+ func getBuildInfoRepositoryByProject (projectKey string ) string {
302+ buildRepo := "artifactory"
303+ if projectKey != "" && projectKey != "default" {
304+ buildRepo = projectKey
305+ }
306+ return buildRepo + "-build-info"
307+ }
308+
109309func testReleaseBundleCreation (t * testing.T , uploadSpec , creationSpec string , expected []string , withoutSigningKey bool ) {
110310 if withoutSigningKey {
111311 cleanCallback := initLifecycleTest (t , signingKeyOptionalArtifactoryMinVersion )
@@ -158,11 +358,12 @@ func TestLifecycleFullFlow(t *testing.T) {
158358
159359 // Export release lifecycle bundle archive
160360
161- tempDir , cleanUp := coreTests .CreateTempDirWithCallbackAndAssert (t )
361+ _ , cleanUp := coreTests .CreateTempDirWithCallbackAndAssert (t )
162362 defer cleanUp ()
163363
164- exportRb (t , tests .LcRbName2 , number2 , tempDir )
165- defer deleteExportedReleaseBundle (t , tests .LcRbName2 )
364+ // TODO Temporarily disabling till export on testing suite is stable.
365+ /*exportRb(t, tests.LcRbName2, number2, tempDir)
366+ defer deleteExportedReleaseBundle(t, tests.LcRbName2)*/
166367
167368 // TODO Temporarily disabling till distribution on testing suite is stable.
168369 /*
@@ -202,9 +403,9 @@ func TestPromoteReleaseBundleWithPromotionTypeFlag(t *testing.T) {
202403 assertStatusCompleted (t , lcManager , tests .LcRbName1 , number1 , "" )
203404}
204405
205- func deleteExportedReleaseBundle (t * testing.T , rbName string ) {
406+ /* func deleteExportedReleaseBundle(t *testing.T, rbName string) {
206407 assert.NoError(t, os.RemoveAll(rbName))
207- }
408+ }*/
208409
209410func assertExpectedArtifacts (t * testing.T , specFileName string , expected []string ) {
210411 searchProdSpec , err := tests .CreateSpec (specFileName )
@@ -255,11 +456,11 @@ func TestCreateBundleWithoutSpec(t *testing.T) {
255456 deleteBuilds := uploadBuilds (t )
256457 defer deleteBuilds ()
257458
258- createRbWithFlags (t , "" , "" , tests .LcBuildName1 , number1 , tests .LcRbName1 , number1 , "" , false , false )
459+ createRbWithFlags (t , "" , "" , tests .LcBuildName1 , number1 , tests .LcRbName1 , number1 , "default " , false , false )
259460 assertStatusCompleted (t , lcManager , tests .LcRbName1 , number1 , "" )
260461 defer deleteReleaseBundle (t , lcManager , tests .LcRbName1 , number1 )
261462
262- createRbWithFlags (t , "" , "" , tests .LcBuildName2 , number2 , tests .LcRbName2 , number2 , "" , false , true )
463+ createRbWithFlags (t , "" , "" , tests .LcBuildName2 , number2 , tests .LcRbName2 , number2 , "default " , false , true )
263464 assertStatusCompleted (t , lcManager , tests .LcRbName2 , number2 , "" )
264465 defer deleteReleaseBundle (t , lcManager , tests .LcRbName2 , number2 )
265466}
@@ -268,11 +469,13 @@ func TestCreateBundleWithoutSpecAndWithProject(t *testing.T) {
268469 cleanCallback := initLifecycleTest (t , signingKeyOptionalArtifactoryMinVersion )
269470 defer cleanCallback ()
270471 deleteProject := createTestProject (t )
271- defer func () {
272- if err := deleteProject (); err != nil {
273- t .Error (err )
274- }
275- }()
472+ if deleteProject != nil {
473+ defer func () {
474+ if err := deleteProject (); err != nil {
475+ t .Error (err )
476+ }
477+ }()
478+ }
276479 lcManager := getLcServiceManager (t )
277480 deleteBuilds := uploadBuildsWithProject (t )
278481 defer deleteBuilds ()
@@ -314,12 +517,12 @@ func createRbWithFlags(t *testing.T, specFilePath, sourceOption, buildName, buil
314517 assert .NoError (t , lcCli .Exec (argsAndOptions ... ))
315518}
316519
317- func exportRb (t * testing.T , rbName , rbVersion , targetPath string ) {
520+ /* func exportRb(t *testing.T, rbName, rbVersion, targetPath string) {
318521 lcCli.RunCliCmdWithOutput(t, "rbe", rbName, rbVersion, targetPath+"/")
319522 exists, err := fileutils.IsDirExists(path.Join(targetPath, rbName), false)
320523 assert.NoError(t, err)
321524 assert.Equal(t, true, exists)
322- }
525+ }*/
323526
324527/*
325528func distributeRb(t *testing.T) {
@@ -629,8 +832,7 @@ func resolveProps(properties string) map[string][]string {
629832 return props .ToMap ()
630833}
631834
632- /*
633- func remoteDeleteReleaseBundle(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion string) {
835+ /*func remoteDeleteReleaseBundle(t *testing.T, lcManager *lifecycle.LifecycleServicesManager, rbName, rbVersion string) {
634836 params := distribution.NewDistributeReleaseBundleParams(rbName, rbVersion)
635837 rules := &distribution.DistributionCommonParams{
636838 SiteName: "*",
@@ -642,8 +844,7 @@ func remoteDeleteReleaseBundle(t *testing.T, lcManager *lifecycle.LifecycleServi
642844 assert.NoError(t, lcManager.RemoteDeleteReleaseBundle(params, false))
643845 // Wait after remote deleting. Can be removed once remote deleting supports sync.
644846 time.Sleep(5 * time.Second)
645- }
646- */
847+ }*/
647848
648849func uploadBuildWithArtifacts (t * testing.T , specFileName , buildName , buildNumber string ) {
649850 specFile , err := tests .CreateSpec (specFileName )
0 commit comments