github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/cnbutils/project/descriptor_test.go (about)

     1  //go:build unit
     2  // +build unit
     3  
     4  package project
     5  
     6  import (
     7  	"net/http"
     8  	"testing"
     9  
    10  	"github.com/SAP/jenkins-library/pkg/cnbutils"
    11  	"github.com/SAP/jenkins-library/pkg/mock"
    12  	"github.com/jarcoal/httpmock"
    13  	"github.com/stretchr/testify/assert"
    14  
    15  	piperhttp "github.com/SAP/jenkins-library/pkg/http"
    16  )
    17  
    18  func TestParseDescriptor(t *testing.T) {
    19  	t.Run("parses the project.toml file v01", func(t *testing.T) {
    20  		projectToml := `[project]
    21  id = "io.buildpacks.my-app"
    22  version = "0.1"
    23  
    24  [build]
    25  include = [
    26  	"cmd/",
    27  	"go.mod",
    28  	"go.sum",
    29  	"*.go"
    30  ]
    31  
    32  [[build.env]]
    33  name = "VAR1"
    34  value = "VAL1"
    35  
    36  [[build.env]]
    37  name = "VAR2"
    38  value = "VAL2"
    39  
    40  [[build.env]]
    41  name = "EMPTY"
    42  value = ""
    43  
    44  [[build.pre.group]]
    45  id = "paketo-buildpacks/java"
    46  version = "5.9.1"
    47  
    48  [[build.post.group]]
    49  id = "paketo-buildpacks/java"
    50  version = "5.9.1"
    51  
    52  [[build.buildpacks]]
    53  id = "paketo-buildpacks/java"
    54  version = "5.9.1"
    55  
    56  [[build.buildpacks]]
    57  id = "paketo-buildpacks/nodejs"
    58  `
    59  		utils := &cnbutils.MockUtils{
    60  			FilesMock: &mock.FilesMock{},
    61  		}
    62  
    63  		fakeJavaResponse := "{\"latest\":{\"version\":\"1.1.1\",\"namespace\":\"test\",\"name\":\"test\",\"description\":\"\",\"homepage\":\"\",\"licenses\":null,\"stacks\":[\"test\",\"test\"],\"id\":\"test\"},\"versions\":[{\"version\":\"5.9.1\",\"_link\":\"https://test-java/5.9.1\"}]}"
    64  		fakeNodeJsResponse := "{\"latest\":{\"version\":\"1.1.1\",\"namespace\":\"test\",\"name\":\"test\",\"description\":\"\",\"homepage\":\"\",\"licenses\":null,\"stacks\":[\"test\",\"test\"],\"id\":\"test\"},\"versions\":[{\"version\":\"1.1.1\",\"_link\":\"https://test-nodejs/1.1.1\"}]}"
    65  
    66  		utils.AddFile("project.toml", []byte(projectToml))
    67  		httpmock.Activate()
    68  		defer httpmock.DeactivateAndReset()
    69  		httpmock.RegisterResponder(http.MethodGet, "https://registry.buildpacks.io/api/v1/buildpacks/paketo-buildpacks/java", httpmock.NewStringResponder(200, fakeJavaResponse))
    70  		httpmock.RegisterResponder(http.MethodGet, "https://registry.buildpacks.io/api/v1/buildpacks/paketo-buildpacks/nodejs", httpmock.NewStringResponder(200, fakeNodeJsResponse))
    71  
    72  		httpmock.RegisterResponder(http.MethodGet, "https://test-java/5.9.1", httpmock.NewStringResponder(200, "{\"addr\": \"index.docker.io/test-java@5.9.1\"}"))
    73  		httpmock.RegisterResponder(http.MethodGet, "https://test-nodejs/1.1.1", httpmock.NewStringResponder(200, "{\"addr\": \"index.docker.io/test-nodejs@1.1.1\"}"))
    74  		client := &piperhttp.Client{}
    75  		client.SetOptions(piperhttp.ClientOptions{MaxRetries: -1, UseDefaultTransport: true})
    76  
    77  		descriptor, err := ParseDescriptor("project.toml", utils, client)
    78  
    79  		assert.NoError(t, err)
    80  		assert.Equal(t, descriptor.EnvVars["VAR1"], "VAL1")
    81  		assert.Equal(t, descriptor.EnvVars["VAR2"], "VAL2")
    82  		assert.Equal(t, descriptor.EnvVars["EMPTY"], "")
    83  
    84  		assert.Equal(t, descriptor.ProjectID, "io.buildpacks.my-app")
    85  
    86  		assert.Contains(t, descriptor.Buildpacks, "index.docker.io/test-java@5.9.1")
    87  		assert.Contains(t, descriptor.Buildpacks, "index.docker.io/test-nodejs@1.1.1")
    88  
    89  		assert.Contains(t, descriptor.PreBuildpacks, "index.docker.io/test-java@5.9.1")
    90  		assert.Contains(t, descriptor.PostBuildpacks, "index.docker.io/test-java@5.9.1")
    91  
    92  		assert.NotNil(t, descriptor.Include)
    93  
    94  		t3 := descriptor.Include.MatchesPath("cmd/cobra.go")
    95  		assert.True(t, t3)
    96  
    97  		t4 := descriptor.Include.MatchesPath("pkg/test/main.go")
    98  		assert.True(t, t4)
    99  
   100  		t5 := descriptor.Include.MatchesPath("Makefile")
   101  		assert.False(t, t5)
   102  	})
   103  
   104  	t.Run("parses the project.toml file v02", func(t *testing.T) {
   105  		projectToml := `[_]
   106  id = "io.buildpacks.my-app"
   107  version = "0.1"
   108  schema-version = "0.2"
   109  
   110  [io.buildpacks]
   111  include = [
   112  	"cmd/",
   113  	"go.mod",
   114  	"go.sum",
   115  	"*.go"
   116  ]
   117  
   118  [[io.buildpacks.build.env]]
   119  name = "VAR1"
   120  value = "VAL1"
   121  
   122  [[io.buildpacks.build.env]]
   123  name = "VAR2"
   124  value = "VAL2"
   125  
   126  [[io.buildpacks.build.env]]
   127  name = "EMPTY"
   128  value = ""
   129  
   130  [[io.buildpacks.pre.group]]
   131  id = "paketo-buildpacks/java"
   132  version = "5.9.1"
   133  
   134  [[io.buildpacks.post.group]]
   135  id = "paketo-buildpacks/java"
   136  version = "5.9.1"
   137  
   138  [[io.buildpacks.group]]
   139  id = "paketo-buildpacks/java"
   140  version = "5.9.1"
   141  
   142  [[io.buildpacks.group]]
   143  id = "paketo-buildpacks/nodejs"
   144  `
   145  		utils := &cnbutils.MockUtils{
   146  			FilesMock: &mock.FilesMock{},
   147  		}
   148  
   149  		fakeJavaResponse := "{\"latest\":{\"version\":\"1.1.1\",\"namespace\":\"test\",\"name\":\"test\",\"description\":\"\",\"homepage\":\"\",\"licenses\":null,\"stacks\":[\"test\",\"test\"],\"id\":\"test\"},\"versions\":[{\"version\":\"5.9.1\",\"_link\":\"https://test-java/5.9.1\"}]}"
   150  		fakeNodeJsResponse := "{\"latest\":{\"version\":\"1.1.1\",\"namespace\":\"test\",\"name\":\"test\",\"description\":\"\",\"homepage\":\"\",\"licenses\":null,\"stacks\":[\"test\",\"test\"],\"id\":\"test\"},\"versions\":[{\"version\":\"1.1.1\",\"_link\":\"https://test-nodejs/1.1.1\"}]}"
   151  
   152  		utils.AddFile("project.toml", []byte(projectToml))
   153  		httpmock.Activate()
   154  		defer httpmock.DeactivateAndReset()
   155  		httpmock.RegisterResponder(http.MethodGet, "https://registry.buildpacks.io/api/v1/buildpacks/paketo-buildpacks/java", httpmock.NewStringResponder(200, fakeJavaResponse))
   156  		httpmock.RegisterResponder(http.MethodGet, "https://registry.buildpacks.io/api/v1/buildpacks/paketo-buildpacks/nodejs", httpmock.NewStringResponder(200, fakeNodeJsResponse))
   157  
   158  		httpmock.RegisterResponder(http.MethodGet, "https://test-java/5.9.1", httpmock.NewStringResponder(200, "{\"addr\": \"index.docker.io/test-java@5.9.1\"}"))
   159  		httpmock.RegisterResponder(http.MethodGet, "https://test-nodejs/1.1.1", httpmock.NewStringResponder(200, "{\"addr\": \"index.docker.io/test-nodejs@1.1.1\"}"))
   160  		client := &piperhttp.Client{}
   161  		client.SetOptions(piperhttp.ClientOptions{MaxRetries: -1, UseDefaultTransport: true})
   162  
   163  		descriptor, err := ParseDescriptor("project.toml", utils, client)
   164  
   165  		assert.NoError(t, err)
   166  		assert.Equal(t, "VAL1", descriptor.EnvVars["VAR1"])
   167  		assert.Equal(t, "VAL2", descriptor.EnvVars["VAR2"])
   168  		assert.Equal(t, "", descriptor.EnvVars["EMPTY"])
   169  
   170  		assert.Equal(t, "io.buildpacks.my-app", descriptor.ProjectID)
   171  
   172  		assert.Contains(t, descriptor.Buildpacks, "index.docker.io/test-java@5.9.1")
   173  		assert.Contains(t, descriptor.Buildpacks, "index.docker.io/test-nodejs@1.1.1")
   174  		assert.Contains(t, descriptor.PreBuildpacks, "index.docker.io/test-java@5.9.1")
   175  		assert.Contains(t, descriptor.PostBuildpacks, "index.docker.io/test-java@5.9.1")
   176  
   177  		assert.NotNil(t, descriptor.Include)
   178  
   179  		t3 := descriptor.Include.MatchesPath("cmd/cobra.go")
   180  		assert.True(t, t3)
   181  
   182  		t4 := descriptor.Include.MatchesPath("pkg/test/main.go")
   183  		assert.True(t, t4)
   184  
   185  		t5 := descriptor.Include.MatchesPath("Makefile")
   186  		assert.False(t, t5)
   187  	})
   188  
   189  	t.Run("fails with inline buildpack", func(t *testing.T) {
   190  		projectToml := `[project]
   191  id = "io.buildpacks.my-app"
   192  version = "0.1"
   193  
   194  [[build.buildpacks]]
   195  id = "test/inline"
   196  	[build.buildpacks.script]
   197  	api = "0.5"
   198  	shell = "/bin/bash"
   199  	inline = "date"
   200  `
   201  		utils := &cnbutils.MockUtils{
   202  			FilesMock: &mock.FilesMock{},
   203  		}
   204  
   205  		utils.AddFile("project.toml", []byte(projectToml))
   206  
   207  		_, err := ParseDescriptor("project.toml", utils, &piperhttp.Client{})
   208  
   209  		assert.Error(t, err)
   210  		assert.Equal(t, "inline buildpacks are not supported", err.Error())
   211  	})
   212  
   213  	t.Run("fails with both exclude and include specified", func(t *testing.T) {
   214  		projectToml := `[project]
   215  id = "io.buildpacks.my-app"
   216  version = "0.1"
   217  
   218  [build]
   219  include = [
   220  	"test"
   221  ]
   222  
   223  exclude = [
   224  	"test"
   225  ]
   226  `
   227  
   228  		utils := &cnbutils.MockUtils{
   229  			FilesMock: &mock.FilesMock{},
   230  		}
   231  		utils.AddFile("project.toml", []byte(projectToml))
   232  
   233  		_, err := ParseDescriptor("project.toml", utils, &piperhttp.Client{})
   234  
   235  		assert.Error(t, err)
   236  		assert.Equal(t, "project descriptor options 'exclude' and 'include' are mutually exclusive", err.Error())
   237  	})
   238  
   239  	t.Run("fails with file not found", func(t *testing.T) {
   240  		utils := &cnbutils.MockUtils{
   241  			FilesMock: &mock.FilesMock{},
   242  		}
   243  
   244  		_, err := ParseDescriptor("project.toml", utils, &piperhttp.Client{})
   245  
   246  		assert.Error(t, err)
   247  		assert.Equal(t, "could not read 'project.toml'", err.Error())
   248  	})
   249  
   250  	t.Run("fails to parse corrupted project.toml", func(t *testing.T) {
   251  		projectToml := "test123"
   252  		utils := &cnbutils.MockUtils{
   253  			FilesMock: &mock.FilesMock{},
   254  		}
   255  		utils.AddFile("project.toml", []byte(projectToml))
   256  		_, err := ParseDescriptor("project.toml", utils, &piperhttp.Client{})
   257  
   258  		assert.Error(t, err)
   259  		assert.Equal(t, "parsing schema version: toml: line 0: unexpected EOF; expected key separator '='", err.Error())
   260  	})
   261  }