github.com/buildpacks/pack@v0.33.3-0.20240516162812-884dd1837311/pkg/buildpack/managed_collection_test.go (about)

     1  package buildpack_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/buildpacks/lifecycle/api"
     7  	"github.com/heroku/color"
     8  	"github.com/sclevine/spec"
     9  	"github.com/sclevine/spec/report"
    10  
    11  	ifakes "github.com/buildpacks/pack/internal/fakes"
    12  	"github.com/buildpacks/pack/pkg/buildpack"
    13  	"github.com/buildpacks/pack/pkg/dist"
    14  	h "github.com/buildpacks/pack/testhelpers"
    15  )
    16  
    17  func TestModuleManager(t *testing.T) {
    18  	color.Disable(true)
    19  	defer color.Disable(false)
    20  	spec.Run(t, "ManagedCollection", testModuleManager, spec.Report(report.Terminal{}))
    21  }
    22  
    23  func testModuleManager(t *testing.T, when spec.G, it spec.S) {
    24  	/* compositeBP1
    25  	 *    /    \
    26  	 *   bp1   compositeBP2
    27  	 *           /   |    \
    28  	 *	      bp21 bp22 compositeBP3
    29  	 *			          |
    30  	 *		            bp31
    31  	 */
    32  	var (
    33  		moduleManager       buildpack.ManagedCollection
    34  		compositeBP1        buildpack.BuildModule
    35  		bp1                 buildpack.BuildModule
    36  		compositeBP2        buildpack.BuildModule
    37  		bp21                buildpack.BuildModule
    38  		bp22                buildpack.BuildModule
    39  		compositeBP3        buildpack.BuildModule
    40  		bp31                buildpack.BuildModule
    41  		flattenBuildModules buildpack.FlattenModuleInfos
    42  		err                 error
    43  	)
    44  
    45  	it.Before(func() {
    46  		bp1, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    47  			WithAPI: api.MustParse("0.2"),
    48  			WithInfo: dist.ModuleInfo{
    49  				ID:      "buildpack-1-id",
    50  				Version: "buildpack-1-version",
    51  			},
    52  		}, 0644)
    53  		h.AssertNil(t, err)
    54  
    55  		bp21, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    56  			WithAPI: api.MustParse("0.2"),
    57  			WithInfo: dist.ModuleInfo{
    58  				ID:      "buildpack-21-id",
    59  				Version: "buildpack-21-version",
    60  			},
    61  		}, 0644)
    62  		h.AssertNil(t, err)
    63  
    64  		bp22, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    65  			WithAPI: api.MustParse("0.2"),
    66  			WithInfo: dist.ModuleInfo{
    67  				ID:      "buildpack-22-id",
    68  				Version: "buildpack-22-version",
    69  			},
    70  		}, 0644)
    71  		h.AssertNil(t, err)
    72  
    73  		bp31, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    74  			WithAPI: api.MustParse("0.2"),
    75  			WithInfo: dist.ModuleInfo{
    76  				ID:      "buildpack-31-id",
    77  				Version: "buildpack-31-version",
    78  			},
    79  		}, 0644)
    80  		h.AssertNil(t, err)
    81  
    82  		compositeBP3, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    83  			WithAPI: api.MustParse("0.2"),
    84  			WithInfo: dist.ModuleInfo{
    85  				ID:      "composite-buildpack-3-id",
    86  				Version: "composite-buildpack-3-version",
    87  			},
    88  			WithOrder: []dist.OrderEntry{{
    89  				Group: []dist.ModuleRef{
    90  					{
    91  						ModuleInfo: bp31.Descriptor().Info(),
    92  					},
    93  				},
    94  			}},
    95  		}, 0644)
    96  		h.AssertNil(t, err)
    97  
    98  		compositeBP2, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    99  			WithAPI: api.MustParse("0.2"),
   100  			WithInfo: dist.ModuleInfo{
   101  				ID:      "composite-buildpack-2-id",
   102  				Version: "composite-buildpack-2-version",
   103  			},
   104  			WithOrder: []dist.OrderEntry{{
   105  				Group: []dist.ModuleRef{
   106  					{
   107  						ModuleInfo: bp21.Descriptor().Info(),
   108  					},
   109  					{
   110  						ModuleInfo: bp22.Descriptor().Info(),
   111  					},
   112  					{
   113  						ModuleInfo: compositeBP3.Descriptor().Info(),
   114  					},
   115  				},
   116  			}},
   117  		}, 0644)
   118  		h.AssertNil(t, err)
   119  
   120  		compositeBP1, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
   121  			WithAPI: api.MustParse("0.2"),
   122  			WithInfo: dist.ModuleInfo{
   123  				ID:      "composite-buildpack-1-id",
   124  				Version: "composite-buildpack-1-version",
   125  			},
   126  			WithOrder: []dist.OrderEntry{{
   127  				Group: []dist.ModuleRef{
   128  					{
   129  						ModuleInfo: bp1.Descriptor().Info(),
   130  					},
   131  					{
   132  						ModuleInfo: compositeBP2.Descriptor().Info(),
   133  					},
   134  				},
   135  			}},
   136  		}, 0644)
   137  		h.AssertNil(t, err)
   138  	})
   139  
   140  	when("manager is configured in flatten mode", func() {
   141  		when("V1 is used", func() {
   142  			when("flatten all", func() {
   143  				it.Before(func() {
   144  					moduleManager = buildpack.NewManagedCollectionV1(true)
   145  					moduleManager.AddModules(compositeBP1, []buildpack.BuildModule{bp1, compositeBP2, bp21, bp22, compositeBP3, bp31}...)
   146  				})
   147  
   148  				when("#FlattenedModules", func() {
   149  					it("returns one flatten module (1 layer)", func() {
   150  						modules := moduleManager.FlattenedModules()
   151  						h.AssertEq(t, len(modules), 1)
   152  						h.AssertEq(t, len(modules[0]), 7)
   153  					})
   154  				})
   155  
   156  				when("#ExplodedModules", func() {
   157  					it("returns empty", func() {
   158  						modules := moduleManager.ExplodedModules()
   159  						h.AssertEq(t, len(modules), 0)
   160  					})
   161  				})
   162  
   163  				when("#AllModules", func() {
   164  					it("returns all explodedModules", func() {
   165  						modules := moduleManager.AllModules()
   166  						h.AssertEq(t, len(modules), 7)
   167  					})
   168  				})
   169  
   170  				when("#ShouldFlatten", func() {
   171  					it("returns true for flatten explodedModules", func() {
   172  						h.AssertTrue(t, moduleManager.ShouldFlatten(compositeBP1))
   173  						h.AssertTrue(t, moduleManager.ShouldFlatten(bp1))
   174  						h.AssertTrue(t, moduleManager.ShouldFlatten(compositeBP2))
   175  						h.AssertTrue(t, moduleManager.ShouldFlatten(bp21))
   176  						h.AssertTrue(t, moduleManager.ShouldFlatten(bp22))
   177  						h.AssertTrue(t, moduleManager.ShouldFlatten(compositeBP3))
   178  						h.AssertTrue(t, moduleManager.ShouldFlatten(bp31))
   179  					})
   180  				})
   181  			})
   182  		})
   183  
   184  		when("V2 is used", func() {
   185  			when("flattened build modules are provided", func() {
   186  				it.Before(func() {
   187  					flattenBuildModules, err = buildpack.ParseFlattenBuildModules([]string{"composite-buildpack-3-id@composite-buildpack-3-version,buildpack-31-id@buildpack-31-version", "composite-buildpack-2-id@composite-buildpack-2-version,buildpack-21-id@buildpack-21-version,buildpack-22-id@buildpack-22-version"})
   188  					h.AssertNil(t, err)
   189  
   190  					moduleManager = buildpack.NewManagedCollectionV2(flattenBuildModules)
   191  					moduleManager.AddModules(compositeBP1, []buildpack.BuildModule{bp1, compositeBP2, bp21, bp22, compositeBP3, bp31}...)
   192  				})
   193  
   194  				when("#FlattenedModules", func() {
   195  					it("returns two flattened modules (2 layers)", func() {
   196  						modules := moduleManager.FlattenedModules()
   197  						h.AssertEq(t, len(modules), 2)
   198  						h.AssertTrue(t, len(modules[0]) == 2 || len(modules[0]) == 3)
   199  						if len(modules[0]) == 2 {
   200  							h.AssertEq(t, len(modules[1]), 3)
   201  						} else if len(modules[0]) == 3 {
   202  							h.AssertEq(t, len(modules[1]), 2)
   203  						}
   204  					})
   205  				})
   206  
   207  				when("#ExplodedModules", func() {
   208  					it("returns two exploded modules: compositeBP1 and bp1", func() {
   209  						modules := moduleManager.ExplodedModules()
   210  						h.AssertEq(t, len(modules), 2)
   211  					})
   212  				})
   213  
   214  				when("#AllModules", func() {
   215  					it("returns all modules", func() {
   216  						modules := moduleManager.AllModules()
   217  						h.AssertEq(t, len(modules), 7)
   218  					})
   219  				})
   220  
   221  				when("#ShouldFlatten", func() {
   222  					it("returns true for flattened modules", func() {
   223  						// exploded modules
   224  						h.AssertFalse(t, moduleManager.ShouldFlatten(compositeBP1))
   225  						h.AssertFalse(t, moduleManager.ShouldFlatten(bp1))
   226  
   227  						// flattened modules
   228  						h.AssertTrue(t, moduleManager.ShouldFlatten(compositeBP2))
   229  						h.AssertTrue(t, moduleManager.ShouldFlatten(bp21))
   230  						h.AssertTrue(t, moduleManager.ShouldFlatten(bp22))
   231  						h.AssertTrue(t, moduleManager.ShouldFlatten(compositeBP3))
   232  						h.AssertTrue(t, moduleManager.ShouldFlatten(bp31))
   233  					})
   234  				})
   235  			})
   236  		})
   237  	})
   238  
   239  	when("manager is not configured in flatten mode", func() {
   240  		when("V1 is used", func() {
   241  			it.Before(func() {
   242  				moduleManager = buildpack.NewManagedCollectionV1(false)
   243  			})
   244  
   245  			when("#ExplodedModules", func() {
   246  				it("returns nil when no explodedModules are added", func() {
   247  					modules := moduleManager.ExplodedModules()
   248  					h.AssertEq(t, len(modules), 0)
   249  				})
   250  
   251  				when("explodedModules are added", func() {
   252  					it.Before(func() {
   253  						moduleManager.AddModules(compositeBP1, []buildpack.BuildModule{bp1, compositeBP2, bp21, bp22, compositeBP3, bp31}...)
   254  					})
   255  					it("returns all explodedModules added", func() {
   256  						modules := moduleManager.ExplodedModules()
   257  						h.AssertEq(t, len(modules), 7)
   258  					})
   259  				})
   260  			})
   261  
   262  			when("#FlattenedModules", func() {
   263  				it("returns nil when no explodedModules are added", func() {
   264  					modules := moduleManager.FlattenedModules()
   265  					h.AssertEq(t, len(modules), 0)
   266  				})
   267  
   268  				when("explodedModules are added", func() {
   269  					it.Before(func() {
   270  						moduleManager.AddModules(compositeBP1, []buildpack.BuildModule{bp1, compositeBP2, bp21, bp22, compositeBP3, bp31}...)
   271  					})
   272  					it("returns nil", func() {
   273  						modules := moduleManager.FlattenedModules()
   274  						h.AssertEq(t, len(modules), 0)
   275  					})
   276  				})
   277  			})
   278  
   279  			when("#ShouldFlatten", func() {
   280  				it("returns false when no explodedModules are added", func() {
   281  					h.AssertFalse(t, moduleManager.ShouldFlatten(bp1))
   282  				})
   283  
   284  				when("explodedModules are added", func() {
   285  					it.Before(func() {
   286  						moduleManager.AddModules(compositeBP1, []buildpack.BuildModule{bp1, compositeBP2, bp21, bp22, compositeBP3, bp31}...)
   287  					})
   288  					it("returns false", func() {
   289  						h.AssertFalse(t, moduleManager.ShouldFlatten(bp1))
   290  						h.AssertFalse(t, moduleManager.ShouldFlatten(bp21))
   291  						h.AssertFalse(t, moduleManager.ShouldFlatten(bp22))
   292  						h.AssertFalse(t, moduleManager.ShouldFlatten(bp31))
   293  					})
   294  				})
   295  			})
   296  		})
   297  
   298  		when("V2 is used", func() {
   299  			it.Before(func() {
   300  				moduleManager = buildpack.NewManagedCollectionV2(nil)
   301  			})
   302  
   303  			when("#ExplodedModules", func() {
   304  				it("returns nil when no explodedModules are added", func() {
   305  					modules := moduleManager.ExplodedModules()
   306  					h.AssertEq(t, len(modules), 0)
   307  				})
   308  
   309  				when("explodedModules are added", func() {
   310  					it.Before(func() {
   311  						moduleManager.AddModules(compositeBP1, []buildpack.BuildModule{bp1, compositeBP2, bp21, bp22, compositeBP3, bp31}...)
   312  					})
   313  					it("returns all explodedModules added", func() {
   314  						modules := moduleManager.ExplodedModules()
   315  						h.AssertEq(t, len(modules), 7)
   316  					})
   317  				})
   318  			})
   319  
   320  			when("#FlattenedModules", func() {
   321  				it("returns nil when no explodedModules are added", func() {
   322  					modules := moduleManager.FlattenedModules()
   323  					h.AssertEq(t, len(modules), 0)
   324  				})
   325  
   326  				when("explodedModules are added", func() {
   327  					it.Before(func() {
   328  						moduleManager.AddModules(compositeBP1, []buildpack.BuildModule{bp1, compositeBP2, bp21, bp22, compositeBP3, bp31}...)
   329  					})
   330  					it("returns nil", func() {
   331  						modules := moduleManager.FlattenedModules()
   332  						h.AssertEq(t, len(modules), 0)
   333  					})
   334  				})
   335  			})
   336  
   337  			when("#ShouldFlatten", func() {
   338  				it("returns false when no explodedModules are added", func() {
   339  					h.AssertFalse(t, moduleManager.ShouldFlatten(bp1))
   340  				})
   341  
   342  				when("explodedModules are added", func() {
   343  					it.Before(func() {
   344  						moduleManager.AddModules(compositeBP1, []buildpack.BuildModule{bp1, compositeBP2, bp21, bp22, compositeBP3, bp31}...)
   345  					})
   346  					it("returns false", func() {
   347  						h.AssertFalse(t, moduleManager.ShouldFlatten(bp1))
   348  						h.AssertFalse(t, moduleManager.ShouldFlatten(bp21))
   349  						h.AssertFalse(t, moduleManager.ShouldFlatten(bp22))
   350  						h.AssertFalse(t, moduleManager.ShouldFlatten(bp31))
   351  					})
   352  				})
   353  			})
   354  		})
   355  	})
   356  }