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 }