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

     1  package buildpack_test
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"testing"
     8  
     9  	"github.com/buildpacks/lifecycle/api"
    10  	"github.com/heroku/color"
    11  	"github.com/sclevine/spec"
    12  	"github.com/sclevine/spec/report"
    13  
    14  	ifakes "github.com/buildpacks/pack/internal/fakes"
    15  	"github.com/buildpacks/pack/internal/style"
    16  	"github.com/buildpacks/pack/pkg/archive"
    17  	"github.com/buildpacks/pack/pkg/buildpack"
    18  	"github.com/buildpacks/pack/pkg/dist"
    19  	"github.com/buildpacks/pack/pkg/logging"
    20  	h "github.com/buildpacks/pack/testhelpers"
    21  )
    22  
    23  func TestBuildModuleWriter(t *testing.T) {
    24  	color.Disable(true)
    25  	defer color.Disable(false)
    26  	spec.Run(t, "testBuildModuleWriter", testBuildModuleWriter, spec.Parallel(), spec.Report(report.Terminal{}))
    27  }
    28  
    29  type void struct{}
    30  
    31  func testBuildModuleWriter(t *testing.T, when spec.G, it spec.S) {
    32  	var (
    33  		outBuf            bytes.Buffer
    34  		logger            logging.Logger
    35  		buildModuleWriter *buildpack.BuildModuleWriter
    36  		bp1v1             buildpack.BuildModule
    37  		bp1v2             buildpack.BuildModule
    38  		bp2v1             buildpack.BuildModule
    39  		bp3v1             buildpack.BuildModule
    40  		member            void
    41  		tmpDir            string
    42  		err               error
    43  	)
    44  
    45  	it.Before(func() {
    46  		logger = logging.NewLogWithWriters(&outBuf, &outBuf, logging.WithVerbose())
    47  		buildModuleWriter = buildpack.NewBuildModuleWriter(logger, archive.DefaultTarWriterFactory())
    48  		tmpDir, err = os.MkdirTemp("", "test_build_module_writer")
    49  		h.AssertNil(t, err)
    50  
    51  		bp1v1, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    52  			WithAPI: api.MustParse("0.2"),
    53  			WithInfo: dist.ModuleInfo{
    54  				ID:      "buildpack-1-id",
    55  				Version: "buildpack-1-version-1",
    56  			},
    57  			WithStacks: []dist.Stack{{
    58  				ID: "*",
    59  			}},
    60  		}, 0644)
    61  		h.AssertNil(t, err)
    62  
    63  		bp1v2, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    64  			WithAPI: api.MustParse("0.2"),
    65  			WithInfo: dist.ModuleInfo{
    66  				ID:      "buildpack-1-id",
    67  				Version: "buildpack-1-version-2",
    68  			},
    69  			WithStacks: []dist.Stack{{
    70  				ID: "*",
    71  			}},
    72  		}, 0644)
    73  		h.AssertNil(t, err)
    74  
    75  		bp2v1, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    76  			WithAPI: api.MustParse("0.2"),
    77  			WithInfo: dist.ModuleInfo{
    78  				ID:      "buildpack-2-id",
    79  				Version: "buildpack-2-version-1",
    80  			},
    81  			WithStacks: []dist.Stack{{
    82  				ID: "*",
    83  			}},
    84  		}, 0644)
    85  		h.AssertNil(t, err)
    86  
    87  		bp3v1, err = ifakes.NewFakeBuildpack(dist.BuildpackDescriptor{
    88  			WithAPI: api.MustParse("0.2"),
    89  			WithInfo: dist.ModuleInfo{
    90  				ID:      "buildpack-3-id",
    91  				Version: "buildpack-3-version-1",
    92  			},
    93  			WithStacks: []dist.Stack{{
    94  				ID: "*",
    95  			}},
    96  		}, 0644)
    97  		h.AssertNil(t, err)
    98  	})
    99  
   100  	it.After(func() {
   101  		err := os.RemoveAll(tmpDir)
   102  		h.AssertNil(t, err)
   103  	})
   104  
   105  	when("#NToLayerTar", func() {
   106  		when("there are not exclude buildpacks", func() {
   107  			when("there are not duplicated buildpacks", func() {
   108  				it("creates a tar", func() {
   109  					bpModules := []buildpack.BuildModule{bp1v1, bp2v1, bp3v1}
   110  					tarFile, bpExcluded, err := buildModuleWriter.NToLayerTar(tmpDir, "test-file-1", bpModules, nil)
   111  
   112  					h.AssertNil(t, err)
   113  					h.AssertTrue(t, len(bpExcluded) == 0)
   114  					h.AssertNotNil(t, tarFile)
   115  					assertBuildpackModuleWritten(t, tarFile, bpModules)
   116  				})
   117  			})
   118  
   119  			when("there are duplicated buildpacks", func() {
   120  				it("creates a tar skipping root folder from duplicated buildpacks", func() {
   121  					bpModules := []buildpack.BuildModule{bp1v1, bp1v2, bp2v1, bp3v1}
   122  					tarFile, bpExcluded, err := buildModuleWriter.NToLayerTar(tmpDir, "test-file-2", bpModules, nil)
   123  
   124  					h.AssertNil(t, err)
   125  					h.AssertTrue(t, len(bpExcluded) == 0)
   126  					h.AssertNotNil(t, tarFile)
   127  					assertBuildpackModuleWritten(t, tarFile, bpModules)
   128  					h.AssertContains(t, outBuf.String(), fmt.Sprintf("folder '%s' was already added, skipping it", "/cnb/buildpacks/buildpack-1-id"))
   129  				})
   130  			})
   131  		})
   132  
   133  		when("there are exclude buildpacks", func() {
   134  			exclude := make(map[string]struct{})
   135  			it.Before(func() {
   136  				exclude[bp2v1.Descriptor().Info().FullName()] = member
   137  			})
   138  
   139  			when("there are not duplicated buildpacks", func() {
   140  				it("creates a tar skipping excluded buildpacks", func() {
   141  					bpModules := []buildpack.BuildModule{bp1v1, bp2v1, bp3v1}
   142  					tarFile, bpExcluded, err := buildModuleWriter.NToLayerTar(tmpDir, "test-file-3", bpModules, exclude)
   143  					h.AssertNil(t, err)
   144  					h.AssertTrue(t, len(bpExcluded) == 1)
   145  					h.AssertNotNil(t, tarFile)
   146  					assertBuildpackModuleWritten(t, tarFile, []buildpack.BuildModule{bp1v1, bp3v1})
   147  					h.AssertContains(t, outBuf.String(), fmt.Sprintf("excluding %s from being flattened", style.Symbol(bp2v1.Descriptor().Info().FullName())))
   148  				})
   149  			})
   150  
   151  			when("there are duplicated buildpacks", func() {
   152  				it("creates a tar skipping excluded buildpacks and root folder from duplicated buildpacks", func() {
   153  					bpModules := []buildpack.BuildModule{bp1v1, bp1v2, bp2v1, bp3v1}
   154  					tarFile, bpExcluded, err := buildModuleWriter.NToLayerTar(tmpDir, "test-file-4", bpModules, exclude)
   155  					h.AssertNil(t, err)
   156  					h.AssertTrue(t, len(bpExcluded) == 1)
   157  					h.AssertNotNil(t, tarFile)
   158  					assertBuildpackModuleWritten(t, tarFile, []buildpack.BuildModule{bp1v1, bp1v2, bp3v1})
   159  					h.AssertContains(t, outBuf.String(), fmt.Sprintf("folder '%s' was already added, skipping it", "/cnb/buildpacks/buildpack-1-id"))
   160  					h.AssertContains(t, outBuf.String(), fmt.Sprintf("excluding %s from being flattened", style.Symbol(bp2v1.Descriptor().Info().FullName())))
   161  				})
   162  			})
   163  		})
   164  	})
   165  }
   166  
   167  func assertBuildpackModuleWritten(t *testing.T, path string, modules []buildpack.BuildModule) {
   168  	t.Helper()
   169  	for _, module := range modules {
   170  		dirPath := fmt.Sprintf("/cnb/buildpacks/%s/%s", module.Descriptor().Info().ID, module.Descriptor().Info().Version)
   171  		h.AssertOnTarEntry(t, path, dirPath,
   172  			h.IsDirectory(),
   173  		)
   174  	}
   175  }