github.com/SAP/jenkins-library@v1.362.0/cmd/golangBuild_test.go (about) 1 //go:build unit 2 // +build unit 3 4 package cmd 5 6 import ( 7 "fmt" 8 "io" 9 "net/http" 10 "os" 11 "path/filepath" 12 "testing" 13 14 piperhttp "github.com/SAP/jenkins-library/pkg/http" 15 "github.com/SAP/jenkins-library/pkg/mock" 16 "github.com/SAP/jenkins-library/pkg/multiarch" 17 "github.com/SAP/jenkins-library/pkg/telemetry" 18 19 "github.com/stretchr/testify/assert" 20 21 "golang.org/x/mod/modfile" 22 "golang.org/x/mod/module" 23 ) 24 25 type golangBuildMockUtils struct { 26 *mock.ExecMockRunner 27 *mock.FilesMock 28 29 returnFileUploadStatus int // expected to be set upfront 30 returnFileUploadError error // expected to be set upfront 31 returnFileDownloadError error // expected to be set upfront 32 returnFileUntarError error // expected to be set upfront 33 34 clientOptions []piperhttp.ClientOptions // set by mock 35 fileUploads map[string]string // set by mock 36 untarFileNames []string 37 } 38 39 func (g *golangBuildMockUtils) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { 40 if g.returnFileDownloadError != nil { 41 return g.returnFileDownloadError 42 } 43 g.AddFile(filename, []byte("content")) 44 return nil 45 } 46 47 func (g *golangBuildMockUtils) GetRepositoryURL(module string) (string, error) { 48 return fmt.Sprintf("https://%s.git", module), nil 49 } 50 51 func (g *golangBuildMockUtils) SendRequest(method string, url string, r io.Reader, header http.Header, cookies []*http.Cookie) (*http.Response, error) { 52 return nil, fmt.Errorf("not implemented") 53 } 54 55 func (g *golangBuildMockUtils) SetOptions(options piperhttp.ClientOptions) { 56 g.clientOptions = append(g.clientOptions, options) 57 } 58 59 func (g *golangBuildMockUtils) UploadRequest(method, url, file, fieldName string, header http.Header, cookies []*http.Cookie, uploadType string) (*http.Response, error) { 60 g.fileUploads[file] = url 61 62 response := http.Response{ 63 StatusCode: g.returnFileUploadStatus, 64 } 65 66 return &response, g.returnFileUploadError 67 } 68 69 func (g *golangBuildMockUtils) UploadFile(url, file, fieldName string, header http.Header, cookies []*http.Cookie, uploadType string) (*http.Response, error) { 70 return g.UploadRequest(http.MethodPut, url, file, fieldName, header, cookies, uploadType) 71 } 72 73 func (g *golangBuildMockUtils) Upload(data piperhttp.UploadRequestData) (*http.Response, error) { 74 return nil, fmt.Errorf("not implemented") 75 } 76 77 func (g *golangBuildMockUtils) getDockerImageValue(stepName string) (string, error) { 78 return "golang:latest", nil 79 } 80 81 func (g *golangBuildMockUtils) Untar(src string, dest string, stripComponentLevel int) error { 82 if g.returnFileUntarError != nil { 83 return g.returnFileUntarError 84 } 85 for _, file := range g.untarFileNames { 86 g.AddFile(filepath.Join(dest, file), []byte("test content")) 87 } 88 return nil 89 } 90 91 func newGolangBuildTestsUtils() *golangBuildMockUtils { 92 utils := golangBuildMockUtils{ 93 ExecMockRunner: &mock.ExecMockRunner{}, 94 FilesMock: &mock.FilesMock{}, 95 // clientOptions: []piperhttp.ClientOptions{}, 96 fileUploads: map[string]string{}, 97 } 98 return &utils 99 } 100 101 func TestRunGolangBuild(t *testing.T) { 102 cpe := golangBuildCommonPipelineEnvironment{} 103 modTestFile := `module private.example.com/test 104 105 require ( 106 example.com/public/module v1.0.0 107 private1.example.com/private/repo v0.1.0 108 private2.example.com/another/repo v0.2.0 109 ) 110 111 go 1.17` 112 113 t.Run("success - no tests", func(t *testing.T) { 114 config := golangBuildOptions{ 115 TargetArchitectures: []string{"linux,amd64"}, 116 } 117 118 utils := newGolangBuildTestsUtils() 119 utils.FilesMock.AddFile("go.mod", []byte(modTestFile)) 120 telemetryData := telemetry.CustomData{} 121 122 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 123 assert.NoError(t, err) 124 assert.Equal(t, "go", utils.ExecMockRunner.Calls[0].Exec) 125 assert.Equal(t, []string{"build", "-trimpath"}, utils.ExecMockRunner.Calls[0].Params) 126 }) 127 128 t.Run("success - tests & ldflags", func(t *testing.T) { 129 config := golangBuildOptions{ 130 RunTests: true, 131 LdflagsTemplate: "test", 132 Packages: []string{"package/foo"}, 133 TargetArchitectures: []string{"linux,amd64"}, 134 } 135 utils := newGolangBuildTestsUtils() 136 utils.FilesMock.AddFile("go.mod", []byte(modTestFile)) 137 telemetryData := telemetry.CustomData{} 138 139 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 140 assert.NoError(t, err) 141 assert.Equal(t, "go", utils.ExecMockRunner.Calls[0].Exec) 142 assert.Equal(t, []string{"install", "gotest.tools/gotestsum@latest"}, utils.ExecMockRunner.Calls[0].Params) 143 assert.Equal(t, "gotestsum", utils.ExecMockRunner.Calls[1].Exec) 144 assert.Equal(t, []string{"--junitfile", "TEST-go.xml", "--jsonfile", "unit-report.out", "--", fmt.Sprintf("-coverprofile=%v", coverageFile), "-tags=unit", "./..."}, utils.ExecMockRunner.Calls[1].Params) 145 assert.Equal(t, "go", utils.ExecMockRunner.Calls[2].Exec) 146 assert.Equal(t, []string{"build", "-trimpath", "-ldflags", "test", "package/foo"}, utils.ExecMockRunner.Calls[2].Params) 147 }) 148 149 t.Run("success - test flags", func(t *testing.T) { 150 config := golangBuildOptions{ 151 RunTests: true, 152 Packages: []string{"package/foo"}, 153 TargetArchitectures: []string{"linux,amd64"}, 154 TestOptions: []string{"--foo", "--bar"}, 155 } 156 utils := newGolangBuildTestsUtils() 157 utils.FilesMock.AddFile("go.mod", []byte(modTestFile)) 158 telemetryData := telemetry.CustomData{} 159 160 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 161 assert.NoError(t, err) 162 assert.Equal(t, "go", utils.ExecMockRunner.Calls[0].Exec) 163 assert.Equal(t, []string{"install", "gotest.tools/gotestsum@latest"}, utils.ExecMockRunner.Calls[0].Params) 164 assert.Equal(t, "gotestsum", utils.ExecMockRunner.Calls[1].Exec) 165 assert.Equal(t, []string{"--junitfile", "TEST-go.xml", "--jsonfile", "unit-report.out", "--", fmt.Sprintf("-coverprofile=%v", coverageFile), "-tags=unit", "./...", "--foo", "--bar"}, utils.ExecMockRunner.Calls[1].Params) 166 assert.Equal(t, "go", utils.ExecMockRunner.Calls[2].Exec) 167 assert.Equal(t, []string{"build", "-trimpath", "package/foo"}, utils.ExecMockRunner.Calls[2].Params) 168 }) 169 170 t.Run("success - tests with coverage", func(t *testing.T) { 171 config := golangBuildOptions{ 172 RunTests: true, 173 ReportCoverage: true, 174 TargetArchitectures: []string{"linux,amd64"}, 175 } 176 utils := newGolangBuildTestsUtils() 177 utils.FilesMock.AddFile("go.mod", []byte(modTestFile)) 178 telemetryData := telemetry.CustomData{} 179 180 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 181 assert.NoError(t, err) 182 assert.Equal(t, "go", utils.ExecMockRunner.Calls[2].Exec) 183 assert.Equal(t, []string{"tool", "cover", "-html", coverageFile, "-o", "coverage.html"}, utils.ExecMockRunner.Calls[2].Params) 184 }) 185 186 t.Run("success - integration tests", func(t *testing.T) { 187 config := golangBuildOptions{ 188 RunIntegrationTests: true, 189 TargetArchitectures: []string{"linux,amd64"}, 190 } 191 utils := newGolangBuildTestsUtils() 192 utils.FilesMock.AddFile("go.mod", []byte(modTestFile)) 193 telemetryData := telemetry.CustomData{} 194 195 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 196 assert.NoError(t, err) 197 assert.Equal(t, "go", utils.ExecMockRunner.Calls[0].Exec) 198 assert.Equal(t, []string{"install", "gotest.tools/gotestsum@latest"}, utils.ExecMockRunner.Calls[0].Params) 199 assert.Equal(t, "gotestsum", utils.ExecMockRunner.Calls[1].Exec) 200 assert.Equal(t, []string{"--junitfile", "TEST-integration.xml", "--jsonfile", "integration-report.out", "--", "-tags=integration", "./..."}, utils.ExecMockRunner.Calls[1].Params) 201 assert.Equal(t, "go", utils.ExecMockRunner.Calls[2].Exec) 202 assert.Equal(t, []string{"build", "-trimpath"}, utils.ExecMockRunner.Calls[2].Params) 203 }) 204 205 t.Run("success - simple publish", func(t *testing.T) { 206 config := golangBuildOptions{ 207 TargetArchitectures: []string{"linux,amd64"}, 208 Publish: true, 209 TargetRepositoryURL: "https://my.target.repository.local/", 210 ArtifactVersion: "1.0.0", 211 } 212 213 utils := newGolangBuildTestsUtils() 214 utils.returnFileUploadStatus = 201 215 utils.FilesMock.AddFile("go.mod", []byte(modTestFile)) 216 telemetryData := telemetry.CustomData{} 217 218 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 219 assert.NoError(t, err) 220 assert.Equal(t, "test", cpe.custom.artifacts[0].Name) 221 }) 222 223 t.Run("success - publishes binaries", func(t *testing.T) { 224 config := golangBuildOptions{ 225 TargetArchitectures: []string{"linux,amd64"}, 226 Output: "testBin", 227 Publish: true, 228 TargetRepositoryURL: "https://my.target.repository.local", 229 TargetRepositoryUser: "user", 230 TargetRepositoryPassword: "password", 231 ArtifactVersion: "1.0.0", 232 } 233 utils := newGolangBuildTestsUtils() 234 utils.returnFileUploadStatus = 201 235 utils.FilesMock.AddFile("go.mod", []byte("module example.com/my/module")) 236 telemetryData := telemetry.CustomData{} 237 238 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 239 if assert.NoError(t, err) { 240 assert.Equal(t, "go", utils.ExecMockRunner.Calls[0].Exec) 241 assert.Equal(t, []string{"build", "-trimpath", "-o", "testBin-linux.amd64"}, utils.ExecMockRunner.Calls[0].Params) 242 243 assert.Equal(t, 1, len(utils.fileUploads)) 244 assert.Equal(t, "https://my.target.repository.local/go/example.com/my/module/1.0.0/testBin-linux.amd64", utils.fileUploads["testBin-linux.amd64"]) 245 } 246 }) 247 248 t.Run("success - publishes binaries (when TargetRepositoryURL ends with slash)", func(t *testing.T) { 249 config := golangBuildOptions{ 250 TargetArchitectures: []string{"linux,amd64"}, 251 Output: "testBin", 252 Publish: true, 253 TargetRepositoryURL: "https://my.target.repository.local/", 254 TargetRepositoryUser: "user", 255 TargetRepositoryPassword: "password", 256 ArtifactVersion: "1.0.0", 257 } 258 utils := newGolangBuildTestsUtils() 259 utils.returnFileUploadStatus = 200 260 utils.FilesMock.AddFile("go.mod", []byte("module example.com/my/module")) 261 telemetryData := telemetry.CustomData{} 262 263 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 264 if assert.NoError(t, err) { 265 assert.Equal(t, "go", utils.ExecMockRunner.Calls[0].Exec) 266 assert.Equal(t, []string{"build", "-trimpath", "-o", "testBin-linux.amd64"}, utils.ExecMockRunner.Calls[0].Params) 267 268 assert.Equal(t, 1, len(utils.fileUploads)) 269 assert.Equal(t, "https://my.target.repository.local/go/example.com/my/module/1.0.0/testBin-linux.amd64", utils.fileUploads["testBin-linux.amd64"]) 270 } 271 }) 272 273 t.Run("success - create BOM", func(t *testing.T) { 274 config := golangBuildOptions{ 275 CreateBOM: true, 276 TargetArchitectures: []string{"linux,amd64"}, 277 } 278 utils := newGolangBuildTestsUtils() 279 utils.FilesMock.AddFile("go.mod", []byte(modTestFile)) 280 telemetryData := telemetry.CustomData{} 281 282 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 283 assert.NoError(t, err) 284 assert.Equal(t, 3, len(utils.ExecMockRunner.Calls)) 285 assert.Equal(t, "go", utils.ExecMockRunner.Calls[0].Exec) 286 assert.Equal(t, []string{"install", "github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@v1.4.0"}, utils.ExecMockRunner.Calls[0].Params) 287 assert.Equal(t, "cyclonedx-gomod", utils.ExecMockRunner.Calls[1].Exec) 288 assert.Equal(t, []string{"mod", "-licenses", "-verbose=false", "-test", "-output", "bom-golang.xml", "-output-version", "1.4"}, utils.ExecMockRunner.Calls[1].Params) 289 assert.Equal(t, "go", utils.ExecMockRunner.Calls[2].Exec) 290 assert.Equal(t, []string{"build", "-trimpath"}, utils.ExecMockRunner.Calls[2].Params) 291 }) 292 293 t.Run("success - RunLint", func(t *testing.T) { 294 goPath := os.Getenv("GOPATH") 295 golangciLintDir := filepath.Join(goPath, "bin") 296 binaryPath := filepath.Join(golangciLintDir, "golangci-lint") 297 298 config := golangBuildOptions{ 299 RunLint: true, 300 } 301 utils := newGolangBuildTestsUtils() 302 utils.AddFile("go.mod", []byte(modTestFile)) 303 telemetry := telemetry.CustomData{} 304 err := runGolangBuild(&config, &telemetry, utils, &cpe) 305 assert.NoError(t, err) 306 307 b, err := utils.FileRead("golangci-lint.tar.gz") 308 assert.NoError(t, err) 309 310 assert.Equal(t, []byte("content"), b) 311 assert.Equal(t, binaryPath, utils.Calls[0].Exec) 312 assert.Equal(t, []string{"run", "--out-format", "checkstyle"}, utils.Calls[0].Params) 313 }) 314 315 t.Run("failure - install pre-requisites for testing", func(t *testing.T) { 316 config := golangBuildOptions{ 317 RunTests: true, 318 } 319 utils := newGolangBuildTestsUtils() 320 utils.ShouldFailOnCommand = map[string]error{"go install gotest.tools/gotestsum": fmt.Errorf("install failure")} 321 telemetryData := telemetry.CustomData{} 322 323 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 324 assert.EqualError(t, err, "failed to install pre-requisite: install failure") 325 }) 326 327 t.Run("failure - install pre-requisites for BOM creation", func(t *testing.T) { 328 config := golangBuildOptions{ 329 CreateBOM: true, 330 } 331 utils := newGolangBuildTestsUtils() 332 utils.ShouldFailOnCommand = map[string]error{"go install github.com/CycloneDX/cyclonedx-gomod/cmd/cyclonedx-gomod@v1.4.0": fmt.Errorf("install failure")} 333 telemetryData := telemetry.CustomData{} 334 335 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 336 assert.EqualError(t, err, "failed to install pre-requisite: install failure") 337 }) 338 339 t.Run("failure - test run failure", func(t *testing.T) { 340 config := golangBuildOptions{ 341 RunTests: true, 342 } 343 utils := newGolangBuildTestsUtils() 344 utils.ShouldFailOnCommand = map[string]error{"gotestsum --junitfile": fmt.Errorf("test failure")} 345 telemetryData := telemetry.CustomData{} 346 347 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 348 assert.EqualError(t, err, "running tests failed - junit result missing: test failure") 349 }) 350 351 t.Run("failure - test failure", func(t *testing.T) { 352 config := golangBuildOptions{ 353 RunTests: true, 354 } 355 utils := newGolangBuildTestsUtils() 356 utils.ShouldFailOnCommand = map[string]error{"gotestsum --junitfile": fmt.Errorf("test failure")} 357 utils.AddFile("TEST-go.xml", []byte("some content")) 358 utils.AddFile(coverageFile, []byte("some content")) 359 telemetryData := telemetry.CustomData{} 360 361 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 362 assert.EqualError(t, err, "some tests failed") 363 }) 364 365 t.Run("failure - prepareLdflags", func(t *testing.T) { 366 config := golangBuildOptions{ 367 RunTests: true, 368 LdflagsTemplate: "{{.CPE.test", 369 TargetArchitectures: []string{"linux,amd64"}, 370 } 371 utils := newGolangBuildTestsUtils() 372 telemetryData := telemetry.CustomData{} 373 374 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 375 assert.Contains(t, fmt.Sprint(err), "failed to parse cpe template") 376 }) 377 378 t.Run("failure - build failure", func(t *testing.T) { 379 config := golangBuildOptions{ 380 RunIntegrationTests: true, 381 TargetArchitectures: []string{"linux,amd64"}, 382 } 383 utils := newGolangBuildTestsUtils() 384 utils.FilesMock.AddFile("go.mod", []byte(modTestFile)) 385 utils.ShouldFailOnCommand = map[string]error{"go build": fmt.Errorf("build failure")} 386 telemetryData := telemetry.CustomData{} 387 388 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 389 assert.EqualError(t, err, "failed to run build for linux.amd64: build failure") 390 }) 391 392 t.Run("failure - publish - no target repository defined", func(t *testing.T) { 393 config := golangBuildOptions{ 394 TargetArchitectures: []string{"linux,amd64"}, 395 Output: "testBin", 396 Publish: true, 397 } 398 utils := newGolangBuildTestsUtils() 399 telemetryData := telemetry.CustomData{} 400 401 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 402 assert.EqualError(t, err, "there's no target repository for binary publishing configured") 403 }) 404 405 t.Run("failure - publish - no go.mod file found", func(t *testing.T) { 406 config := golangBuildOptions{ 407 TargetArchitectures: []string{"linux,amd64"}, 408 Output: "testBin", 409 Publish: true, 410 TargetRepositoryURL: "https://my.target.repository.local", 411 TargetRepositoryUser: "user", 412 TargetRepositoryPassword: "password", 413 ArtifactVersion: "1.0.0", 414 } 415 utils := newGolangBuildTestsUtils() 416 telemetryData := telemetry.CustomData{} 417 418 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 419 assert.EqualError(t, err, "go.mod file not found") 420 }) 421 422 t.Run("failure - publish - go.mod file without module path", func(t *testing.T) { 423 config := golangBuildOptions{ 424 TargetArchitectures: []string{"linux,amd64"}, 425 Output: "testBin", 426 Publish: true, 427 TargetRepositoryURL: "https://my.target.repository.local", 428 TargetRepositoryUser: "user", 429 TargetRepositoryPassword: "password", 430 ArtifactVersion: "1.0.0", 431 } 432 utils := newGolangBuildTestsUtils() 433 utils.FilesMock.AddFile("go.mod", []byte("")) 434 telemetryData := telemetry.CustomData{} 435 436 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 437 assert.EqualError(t, err, "go.mod doesn't declare a module path") 438 }) 439 440 t.Run("failure - publish - no artifactVersion set", func(t *testing.T) { 441 config := golangBuildOptions{ 442 TargetArchitectures: []string{"linux,amd64"}, 443 Output: "testBin", 444 Publish: true, 445 TargetRepositoryURL: "https://my.target.repository.local", 446 TargetRepositoryUser: "user", 447 TargetRepositoryPassword: "password", 448 } 449 utils := newGolangBuildTestsUtils() 450 utils.FilesMock.AddFile("go.mod", []byte("module example.com/my/module")) 451 telemetryData := telemetry.CustomData{} 452 453 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 454 assert.EqualError(t, err, "no build descriptor available, supported: [go.mod VERSION version.txt]") 455 }) 456 457 t.Run("failure - publish - received unexpected status code", func(t *testing.T) { 458 config := golangBuildOptions{ 459 TargetArchitectures: []string{"linux,amd64"}, 460 Output: "testBin", 461 Publish: true, 462 TargetRepositoryURL: "https://my.target.repository.local", 463 TargetRepositoryUser: "user", 464 TargetRepositoryPassword: "password", 465 ArtifactVersion: "1.0.0", 466 } 467 utils := newGolangBuildTestsUtils() 468 utils.returnFileUploadStatus = 500 469 utils.FilesMock.AddFile("go.mod", []byte("module example.com/my/module")) 470 telemetryData := telemetry.CustomData{} 471 472 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 473 assert.EqualError(t, err, "couldn't upload artifact, received status code 500") 474 }) 475 476 t.Run("failure - create BOM", func(t *testing.T) { 477 config := golangBuildOptions{ 478 CreateBOM: true, 479 TargetArchitectures: []string{"linux,amd64"}, 480 } 481 GeneralConfig.Verbose = false 482 utils := newGolangBuildTestsUtils() 483 utils.ShouldFailOnCommand = map[string]error{"cyclonedx-gomod mod -licenses -verbose=false -test -output bom-golang.xml -output-version 1.4": fmt.Errorf("BOM creation failure")} 484 telemetryData := telemetry.CustomData{} 485 486 err := runGolangBuild(&config, &telemetryData, utils, &cpe) 487 assert.EqualError(t, err, "BOM creation failed: BOM creation failure") 488 }) 489 490 t.Run("failure - RunLint: retrieveGolangciLint failed", func(t *testing.T) { 491 config := golangBuildOptions{ 492 RunLint: true, 493 } 494 495 utils := newGolangBuildTestsUtils() 496 utils.AddFile("go.mod", []byte(modTestFile)) 497 utils.returnFileDownloadError = fmt.Errorf("downloading error") 498 telemetry := telemetry.CustomData{} 499 err := runGolangBuild(&config, &telemetry, utils, &cpe) 500 assert.EqualError(t, err, "failed to download golangci-lint: downloading error") 501 }) 502 503 t.Run("failure - RunLint: runGolangciLint failed", func(t *testing.T) { 504 goPath := os.Getenv("GOPATH") 505 golangciLintDir := filepath.Join(goPath, "bin") 506 binaryPath := filepath.Join(golangciLintDir, "golangci-lint") 507 508 config := golangBuildOptions{ 509 RunLint: true, 510 } 511 utils := newGolangBuildTestsUtils() 512 utils.AddFile("go.mod", []byte(modTestFile)) 513 utils.ShouldFailOnCommand = map[string]error{fmt.Sprintf("%s run --out-format checkstyle", binaryPath): fmt.Errorf("err")} 514 telemetry := telemetry.CustomData{} 515 err := runGolangBuild(&config, &telemetry, utils, &cpe) 516 assert.EqualError(t, err, "running golangci-lint failed: err") 517 }) 518 } 519 520 func TestRunGolangTests(t *testing.T) { 521 t.Parallel() 522 523 t.Run("success", func(t *testing.T) { 524 t.Parallel() 525 config := golangBuildOptions{} 526 utils := newGolangBuildTestsUtils() 527 utils.AddFile("TEST-go.xml", []byte("some content")) 528 utils.AddFile(coverageFile, []byte("some content")) 529 530 success, err := runGolangTests(&config, utils) 531 assert.NoError(t, err) 532 assert.True(t, success) 533 assert.Equal(t, "gotestsum", utils.ExecMockRunner.Calls[0].Exec) 534 assert.Equal(t, []string{"--junitfile", "TEST-go.xml", "--jsonfile", "unit-report.out", "--", fmt.Sprintf("-coverprofile=%v", coverageFile), "-tags=unit", "./..."}, utils.ExecMockRunner.Calls[0].Params) 535 }) 536 537 t.Run("success - failed tests", func(t *testing.T) { 538 t.Parallel() 539 config := golangBuildOptions{} 540 utils := newGolangBuildTestsUtils() 541 utils.AddFile("TEST-go.xml", []byte("some content")) 542 utils.AddFile(coverageFile, []byte("some content")) 543 utils.ExecMockRunner.ShouldFailOnCommand = map[string]error{"gotestsum": fmt.Errorf("execution error")} 544 545 success, err := runGolangTests(&config, utils) 546 assert.NoError(t, err) 547 assert.False(t, success) 548 }) 549 550 t.Run("error - run failed, no junit", func(t *testing.T) { 551 t.Parallel() 552 config := golangBuildOptions{} 553 utils := newGolangBuildTestsUtils() 554 utils.ExecMockRunner.ShouldFailOnCommand = map[string]error{"gotestsum": fmt.Errorf("execution error")} 555 556 _, err := runGolangTests(&config, utils) 557 assert.EqualError(t, err, "running tests failed - junit result missing: execution error") 558 }) 559 560 t.Run("error - run failed, no coverage", func(t *testing.T) { 561 t.Parallel() 562 config := golangBuildOptions{} 563 utils := newGolangBuildTestsUtils() 564 utils.ExecMockRunner.ShouldFailOnCommand = map[string]error{"gotestsum": fmt.Errorf("execution error")} 565 utils.AddFile("TEST-go.xml", []byte("some content")) 566 567 _, err := runGolangTests(&config, utils) 568 assert.EqualError(t, err, "running tests failed - coverage output missing: execution error") 569 }) 570 } 571 572 func TestRunGolangIntegrationTests(t *testing.T) { 573 t.Parallel() 574 575 t.Run("success", func(t *testing.T) { 576 t.Parallel() 577 config := golangBuildOptions{} 578 utils := newGolangBuildTestsUtils() 579 utils.AddFile("TEST-integration.xml", []byte("some content")) 580 581 success, err := runGolangIntegrationTests(&config, utils) 582 assert.NoError(t, err) 583 assert.True(t, success) 584 assert.Equal(t, "gotestsum", utils.ExecMockRunner.Calls[0].Exec) 585 assert.Equal(t, []string{"--junitfile", "TEST-integration.xml", "--jsonfile", "integration-report.out", "--", "-tags=integration", "./..."}, utils.ExecMockRunner.Calls[0].Params) 586 }) 587 588 t.Run("success - failed tests", func(t *testing.T) { 589 t.Parallel() 590 config := golangBuildOptions{} 591 utils := newGolangBuildTestsUtils() 592 utils.AddFile("TEST-integration.xml", []byte("some content")) 593 utils.ExecMockRunner.ShouldFailOnCommand = map[string]error{"gotestsum": fmt.Errorf("execution error")} 594 595 success, err := runGolangIntegrationTests(&config, utils) 596 assert.NoError(t, err) 597 assert.False(t, success) 598 }) 599 600 t.Run("error - run failed", func(t *testing.T) { 601 t.Parallel() 602 config := golangBuildOptions{} 603 utils := newGolangBuildTestsUtils() 604 utils.ExecMockRunner.ShouldFailOnCommand = map[string]error{"gotestsum": fmt.Errorf("execution error")} 605 606 _, err := runGolangIntegrationTests(&config, utils) 607 assert.EqualError(t, err, "running tests failed: execution error") 608 }) 609 } 610 611 func TestReportGolangTestCoverage(t *testing.T) { 612 t.Parallel() 613 614 t.Run("success - cobertura", func(t *testing.T) { 615 t.Parallel() 616 config := golangBuildOptions{CoverageFormat: "cobertura"} 617 utils := newGolangBuildTestsUtils() 618 utils.AddFile(coverageFile, []byte("some content")) 619 620 err := reportGolangTestCoverage(&config, utils) 621 assert.NoError(t, err) 622 assert.Equal(t, "go", utils.ExecMockRunner.Calls[0].Exec) 623 assert.Equal(t, []string{"install", "github.com/boumenot/gocover-cobertura@latest"}, utils.ExecMockRunner.Calls[0].Params) 624 assert.Equal(t, "gocover-cobertura", utils.ExecMockRunner.Calls[1].Exec) 625 exists, err := utils.FileExists("cobertura-coverage.xml") 626 assert.NoError(t, err) 627 assert.True(t, exists) 628 }) 629 630 t.Run("success - cobertura exclude generated", func(t *testing.T) { 631 t.Parallel() 632 config := golangBuildOptions{CoverageFormat: "cobertura", ExcludeGeneratedFromCoverage: true} 633 utils := newGolangBuildTestsUtils() 634 utils.AddFile(coverageFile, []byte("some content")) 635 636 err := reportGolangTestCoverage(&config, utils) 637 assert.NoError(t, err) 638 assert.Equal(t, "gocover-cobertura", utils.ExecMockRunner.Calls[1].Exec) 639 assert.Equal(t, []string{"-ignore-gen-files"}, utils.ExecMockRunner.Calls[1].Params) 640 }) 641 642 t.Run("error - cobertura installation", func(t *testing.T) { 643 t.Parallel() 644 config := golangBuildOptions{CoverageFormat: "cobertura", ExcludeGeneratedFromCoverage: true} 645 utils := newGolangBuildTestsUtils() 646 utils.ExecMockRunner.ShouldFailOnCommand = map[string]error{"go install github.com/boumenot/gocover-cobertura": fmt.Errorf("install error")} 647 648 err := reportGolangTestCoverage(&config, utils) 649 assert.EqualError(t, err, "failed to install pre-requisite: install error") 650 }) 651 652 t.Run("error - cobertura missing coverage file", func(t *testing.T) { 653 t.Parallel() 654 config := golangBuildOptions{CoverageFormat: "cobertura", ExcludeGeneratedFromCoverage: true} 655 utils := newGolangBuildTestsUtils() 656 657 err := reportGolangTestCoverage(&config, utils) 658 assert.Contains(t, fmt.Sprint(err), "failed to read coverage file") 659 }) 660 661 t.Run("error - cobertura coversion", func(t *testing.T) { 662 t.Parallel() 663 config := golangBuildOptions{CoverageFormat: "cobertura", ExcludeGeneratedFromCoverage: true} 664 utils := newGolangBuildTestsUtils() 665 utils.AddFile(coverageFile, []byte("some content")) 666 utils.ExecMockRunner.ShouldFailOnCommand = map[string]error{"gocover-cobertura -ignore-gen-files": fmt.Errorf("execution error")} 667 668 err := reportGolangTestCoverage(&config, utils) 669 assert.EqualError(t, err, "failed to convert coverage data to cobertura format: execution error") 670 }) 671 672 t.Run("error - writing cobertura file", func(t *testing.T) { 673 t.Parallel() 674 config := golangBuildOptions{CoverageFormat: "cobertura", ExcludeGeneratedFromCoverage: true} 675 utils := newGolangBuildTestsUtils() 676 utils.AddFile(coverageFile, []byte("some content")) 677 utils.FileWriteError = fmt.Errorf("write failure") 678 679 err := reportGolangTestCoverage(&config, utils) 680 assert.EqualError(t, err, "failed to create cobertura coverage file: write failure") 681 }) 682 683 t.Run("success - html", func(t *testing.T) { 684 t.Parallel() 685 config := golangBuildOptions{} 686 utils := newGolangBuildTestsUtils() 687 688 err := reportGolangTestCoverage(&config, utils) 689 assert.NoError(t, err) 690 assert.Equal(t, "go", utils.ExecMockRunner.Calls[0].Exec) 691 assert.Equal(t, []string{"tool", "cover", "-html", coverageFile, "-o", "coverage.html"}, utils.ExecMockRunner.Calls[0].Params) 692 }) 693 694 t.Run("error - html", func(t *testing.T) { 695 t.Parallel() 696 config := golangBuildOptions{} 697 utils := newGolangBuildTestsUtils() 698 utils.ExecMockRunner.ShouldFailOnCommand = map[string]error{"go tool cover -html cover.out -o coverage.html": fmt.Errorf("execution error")} 699 utils.AddFile(coverageFile, []byte("some content")) 700 701 err := reportGolangTestCoverage(&config, utils) 702 assert.EqualError(t, err, "failed to create html coverage file: execution error") 703 }) 704 } 705 706 func TestPrepareLdflags(t *testing.T) { 707 t.Parallel() 708 dir := t.TempDir() 709 710 err := os.Mkdir(filepath.Join(dir, "commonPipelineEnvironment"), 0o777) 711 assert.NoError(t, err, "Error when creating folder structure") 712 713 err = os.WriteFile(filepath.Join(dir, "commonPipelineEnvironment", "artifactVersion"), []byte("1.2.3"), 0666) 714 assert.NoError(t, err, "Error when creating cpe file") 715 716 t.Run("success - default", func(t *testing.T) { 717 config := golangBuildOptions{LdflagsTemplate: "-X version={{ .CPE.artifactVersion }}"} 718 utils := newGolangBuildTestsUtils() 719 result, err := prepareLdflags(&config, utils, dir) 720 assert.NoError(t, err) 721 assert.Equal(t, "-X version=1.2.3", (*result).String()) 722 }) 723 724 t.Run("error - template parsing", func(t *testing.T) { 725 config := golangBuildOptions{LdflagsTemplate: "-X version={{ .CPE.artifactVersion "} 726 utils := newGolangBuildTestsUtils() 727 _, err := prepareLdflags(&config, utils, dir) 728 assert.Contains(t, fmt.Sprint(err), "failed to parse cpe template") 729 }) 730 } 731 732 func TestRunGolangBuildPerArchitecture(t *testing.T) { 733 t.Parallel() 734 735 t.Run("success - default", func(t *testing.T) { 736 t.Parallel() 737 config := golangBuildOptions{} 738 utils := newGolangBuildTestsUtils() 739 ldflags := "" 740 architecture, _ := multiarch.ParsePlatformString("linux,amd64") 741 goModFile := modfile.File{Module: &modfile.Module{Mod: module.Version{Path: "test/testBinary"}}} 742 743 binaryName, err := runGolangBuildPerArchitecture(&config, &goModFile, utils, ldflags, architecture) 744 assert.NoError(t, err) 745 assert.Greater(t, len(utils.Env), 3) 746 assert.Contains(t, utils.Env, "CGO_ENABLED=0") 747 assert.Contains(t, utils.Env, "GOOS=linux") 748 assert.Contains(t, utils.Env, "GOARCH=amd64") 749 assert.Equal(t, utils.Calls[0].Exec, "go") 750 assert.Equal(t, utils.Calls[0].Params[0], "build") 751 assert.Equal(t, binaryName[0], "testBinary") 752 }) 753 754 t.Run("success - custom params", func(t *testing.T) { 755 t.Parallel() 756 config := golangBuildOptions{BuildFlags: []string{"--flag1", "val1", "--flag2", "val2"}, Output: "testBin", Packages: []string{"./test/.."}} 757 utils := newGolangBuildTestsUtils() 758 ldflags := "-X test=test" 759 architecture, _ := multiarch.ParsePlatformString("linux,amd64") 760 goModFile := modfile.File{Module: &modfile.Module{Mod: module.Version{Path: "test/testBinary"}}} 761 762 binaryNames, err := runGolangBuildPerArchitecture(&config, &goModFile, utils, ldflags, architecture) 763 assert.NoError(t, err) 764 assert.Contains(t, utils.Calls[0].Params, "-o") 765 assert.Contains(t, utils.Calls[0].Params, "testBin-linux.amd64") 766 assert.Contains(t, utils.Calls[0].Params, "./test/..") 767 assert.Contains(t, utils.Calls[0].Params, "-ldflags") 768 assert.Contains(t, utils.Calls[0].Params, "-X test=test") 769 assert.Len(t, binaryNames, 1) 770 assert.Contains(t, binaryNames, "testBin-linux.amd64") 771 }) 772 773 t.Run("success - windows", func(t *testing.T) { 774 t.Parallel() 775 config := golangBuildOptions{Output: "testBin"} 776 utils := newGolangBuildTestsUtils() 777 ldflags := "" 778 architecture, _ := multiarch.ParsePlatformString("windows,amd64") 779 goModFile := modfile.File{Module: &modfile.Module{Mod: module.Version{Path: "test/testBinary"}}} 780 781 binaryNames, err := runGolangBuildPerArchitecture(&config, &goModFile, utils, ldflags, architecture) 782 assert.NoError(t, err) 783 assert.Contains(t, utils.Calls[0].Params, "-o") 784 assert.Contains(t, utils.Calls[0].Params, "testBin-windows.amd64.exe") 785 assert.Len(t, binaryNames, 1) 786 assert.Contains(t, binaryNames, "testBin-windows.amd64.exe") 787 }) 788 789 t.Run("success - multiple main packages (linux)", func(t *testing.T) { 790 t.Parallel() 791 config := golangBuildOptions{Output: "test/", Packages: []string{"package/foo", "package/bar"}} 792 utils := newGolangBuildTestsUtils() 793 utils.StdoutReturn = map[string]string{ 794 "go list -f {{ .Name }} package/foo": "main", 795 "go list -f {{ .Name }} package/bar": "main", 796 } 797 ldflags := "" 798 architecture, _ := multiarch.ParsePlatformString("linux,amd64") 799 goModFile := modfile.File{Module: &modfile.Module{Mod: module.Version{Path: "test/testBinary"}}} 800 801 binaryNames, err := runGolangBuildPerArchitecture(&config, &goModFile, utils, ldflags, architecture) 802 assert.NoError(t, err) 803 assert.Contains(t, utils.Calls[0].Params, "list") 804 assert.Contains(t, utils.Calls[0].Params, "package/foo") 805 assert.Contains(t, utils.Calls[1].Params, "list") 806 assert.Contains(t, utils.Calls[1].Params, "package/bar") 807 808 assert.Len(t, binaryNames, 2) 809 assert.Contains(t, binaryNames, "test-linux-amd64/foo") 810 assert.Contains(t, binaryNames, "test-linux-amd64/bar") 811 }) 812 813 t.Run("success - multiple main packages (windows)", func(t *testing.T) { 814 t.Parallel() 815 config := golangBuildOptions{Output: "test/", Packages: []string{"package/foo", "package/bar"}} 816 utils := newGolangBuildTestsUtils() 817 utils.StdoutReturn = map[string]string{ 818 "go list -f {{ .Name }} package/foo": "main", 819 "go list -f {{ .Name }} package/bar": "main", 820 } 821 ldflags := "" 822 architecture, _ := multiarch.ParsePlatformString("windows,amd64") 823 goModFile := modfile.File{Module: &modfile.Module{Mod: module.Version{Path: "test/testBinary"}}} 824 825 binaryNames, err := runGolangBuildPerArchitecture(&config, &goModFile, utils, ldflags, architecture) 826 assert.NoError(t, err) 827 assert.Contains(t, utils.Calls[0].Params, "list") 828 assert.Contains(t, utils.Calls[0].Params, "package/foo") 829 assert.Contains(t, utils.Calls[1].Params, "list") 830 assert.Contains(t, utils.Calls[1].Params, "package/bar") 831 832 assert.Len(t, binaryNames, 2) 833 assert.Contains(t, binaryNames, "test-windows-amd64/foo.exe") 834 assert.Contains(t, binaryNames, "test-windows-amd64/bar.exe") 835 }) 836 837 t.Run("success - multiple mixed packages", func(t *testing.T) { 838 t.Parallel() 839 config := golangBuildOptions{Output: "test/", Packages: []string{"package/foo", "package/bar"}} 840 utils := newGolangBuildTestsUtils() 841 utils.StdoutReturn = map[string]string{ 842 "go list -f {{ .Name }} package/foo": "main", 843 "go list -f {{ .Name }} package/bar": "bar", 844 } 845 ldflags := "" 846 architecture, _ := multiarch.ParsePlatformString("linux,amd64") 847 goModFile := modfile.File{Module: &modfile.Module{Mod: module.Version{Path: "test/testBinary"}}} 848 849 binaryNames, err := runGolangBuildPerArchitecture(&config, &goModFile, utils, ldflags, architecture) 850 assert.NoError(t, err) 851 assert.Contains(t, utils.Calls[0].Params, "list") 852 assert.Contains(t, utils.Calls[0].Params, "package/foo") 853 assert.Contains(t, utils.Calls[1].Params, "list") 854 assert.Contains(t, utils.Calls[1].Params, "package/bar") 855 856 assert.Len(t, binaryNames, 1) 857 assert.Contains(t, binaryNames, "test-linux-amd64/foo") 858 }) 859 860 t.Run("execution error", func(t *testing.T) { 861 t.Parallel() 862 config := golangBuildOptions{} 863 utils := newGolangBuildTestsUtils() 864 utils.ShouldFailOnCommand = map[string]error{"go build": fmt.Errorf("execution error")} 865 ldflags := "" 866 architecture, _ := multiarch.ParsePlatformString("linux,amd64") 867 goModFile := modfile.File{Module: &modfile.Module{Mod: module.Version{Path: "test/testBinary"}}} 868 869 _, err := runGolangBuildPerArchitecture(&config, &goModFile, utils, ldflags, architecture) 870 assert.EqualError(t, err, "failed to run build for linux.amd64: execution error") 871 }) 872 } 873 874 func TestPrepareGolangEnvironment(t *testing.T) { 875 modTestFile := ` 876 module private.example.com/m 877 878 require ( 879 example.com/public/module v1.0.0 880 private1.example.com/private/repo v0.1.0 881 private2.example.com/another/repo v0.2.0 882 ) 883 884 go 1.17` 885 886 type expectations struct { 887 envVars []string 888 commandsExecuted [][]string 889 } 890 tests := []struct { 891 name string 892 modFileContent string 893 globPattern string 894 gitToken string 895 expect expectations 896 }{ 897 { 898 name: "success - does nothing if privateModules is not set", 899 modFileContent: modTestFile, 900 globPattern: "", 901 gitToken: "secret", 902 expect: expectations{}, 903 }, 904 { 905 name: "success - goprivate is set and authentication properly configured", 906 modFileContent: modTestFile, 907 globPattern: "*.example.com", 908 gitToken: "secret", 909 expect: expectations{ 910 envVars: []string{"GOPRIVATE=*.example.com"}, 911 commandsExecuted: [][]string{ 912 {"git", "config", "--global", "url.https://secret@example.com.insteadOf", "https://example.com"}, 913 }, 914 }, 915 }, 916 } 917 918 for _, tt := range tests { 919 t.Run(tt.name, func(t *testing.T) { 920 utils := newGolangBuildTestsUtils() 921 922 goModFile, _ := modfile.Parse("go.mod", []byte(tt.modFileContent), nil) 923 924 config := golangBuildOptions{} 925 config.PrivateModules = tt.globPattern 926 config.PrivateModulesGitToken = tt.gitToken 927 928 err := prepareGolangEnvironment(&config, goModFile, utils) 929 930 if assert.NoError(t, err) { 931 assert.Subset(t, os.Environ(), tt.expect.envVars) 932 assert.Equal(t, len(tt.expect.commandsExecuted), len(utils.Calls)) 933 934 for i, expectedCommand := range tt.expect.commandsExecuted { 935 assert.Equal(t, expectedCommand[0], utils.Calls[i].Exec) 936 assert.Equal(t, expectedCommand[1:], utils.Calls[i].Params) 937 } 938 } 939 }) 940 } 941 } 942 943 func TestRunGolangciLint(t *testing.T) { 944 t.Parallel() 945 946 goPath := os.Getenv("GOPATH") 947 golangciLintDir := filepath.Join(goPath, "bin") 948 binaryPath := filepath.Join(golangciLintDir, "golangci-lint") 949 950 lintSettings := map[string]string{ 951 "reportStyle": "checkstyle", 952 "reportOutputPath": "golangci-lint-report.xml", 953 "additionalParams": "", 954 } 955 956 tt := []struct { 957 name string 958 shouldFailOnCommand map[string]error 959 fileWriteError error 960 exitCode int 961 expectedCommand []string 962 expectedErr error 963 failOnLintingError bool 964 }{ 965 { 966 name: "success", 967 shouldFailOnCommand: map[string]error{}, 968 fileWriteError: nil, 969 exitCode: 0, 970 expectedCommand: []string{binaryPath, "run", "--out-format", lintSettings["reportStyle"]}, 971 expectedErr: nil, 972 }, 973 { 974 name: "failure - failed to run golangci-lint", 975 shouldFailOnCommand: map[string]error{fmt.Sprintf("%s run --out-format %s", binaryPath, lintSettings["reportStyle"]): fmt.Errorf("err")}, 976 fileWriteError: nil, 977 exitCode: 0, 978 expectedCommand: []string{}, 979 expectedErr: fmt.Errorf("running golangci-lint failed: err"), 980 }, 981 { 982 name: "failure - failed to write golangci-lint report", 983 shouldFailOnCommand: map[string]error{}, 984 fileWriteError: fmt.Errorf("failed to write golangci-lint report"), 985 exitCode: 0, 986 expectedCommand: []string{}, 987 expectedErr: fmt.Errorf("writing golangci-lint report failed: failed to write golangci-lint report"), 988 }, 989 { 990 name: "failure - failed with ExitCode == 1", 991 shouldFailOnCommand: map[string]error{}, 992 exitCode: 1, 993 expectedCommand: []string{}, 994 expectedErr: fmt.Errorf("golangci-lint found issues, see report above"), 995 failOnLintingError: true, 996 }, 997 { 998 name: "success - ignore failed with ExitCode == 1", 999 shouldFailOnCommand: map[string]error{}, 1000 exitCode: 1, 1001 expectedCommand: []string{binaryPath, "run", "--out-format", lintSettings["reportStyle"]}, 1002 expectedErr: nil, 1003 failOnLintingError: false, 1004 }, 1005 } 1006 1007 for _, test := range tt { 1008 test := test 1009 t.Run(test.name, func(t *testing.T) { 1010 t.Parallel() 1011 utils := newGolangBuildTestsUtils() 1012 utils.ShouldFailOnCommand = test.shouldFailOnCommand 1013 utils.FileWriteError = test.fileWriteError 1014 utils.ExitCode = test.exitCode 1015 err := runGolangciLint(utils, golangciLintDir, test.failOnLintingError, lintSettings) 1016 1017 if test.expectedErr == nil { 1018 assert.Equal(t, test.expectedCommand[0], utils.Calls[0].Exec) 1019 assert.Equal(t, test.expectedCommand[1:], utils.Calls[0].Params) 1020 } else { 1021 assert.EqualError(t, err, test.expectedErr.Error()) 1022 } 1023 }) 1024 } 1025 } 1026 1027 func TestRetrieveGolangciLint(t *testing.T) { 1028 t.Parallel() 1029 1030 goPath := os.Getenv("GOPATH") 1031 golangciLintDir := filepath.Join(goPath, "bin") 1032 1033 tt := []struct { 1034 name string 1035 downloadErr error 1036 untarErr error 1037 expectedErr error 1038 }{ 1039 { 1040 name: "success", 1041 }, 1042 { 1043 name: "failure - failed to download golangci-lint", 1044 downloadErr: fmt.Errorf("download err"), 1045 expectedErr: fmt.Errorf("failed to download golangci-lint: download err"), 1046 }, 1047 { 1048 name: "failure - failed to install golangci-lint", 1049 untarErr: fmt.Errorf("retrieve archive err"), 1050 expectedErr: fmt.Errorf("failed to install golangci-lint: retrieve archive err"), 1051 }, 1052 } 1053 1054 for _, test := range tt { 1055 test := test 1056 t.Run(test.name, func(t *testing.T) { 1057 t.Parallel() 1058 utils := newGolangBuildTestsUtils() 1059 utils.returnFileDownloadError = test.downloadErr 1060 utils.returnFileUntarError = test.untarErr 1061 utils.untarFileNames = []string{"golangci-lint"} 1062 config := golangBuildOptions{ 1063 GolangciLintURL: "https://github.com/golangci/golangci-lint/releases/download/v1.50.1/golangci-lint-1.50.0-darwin-amd64.tar.gz", 1064 } 1065 err := retrieveGolangciLint(utils, golangciLintDir, config.GolangciLintURL) 1066 1067 if test.expectedErr != nil { 1068 assert.EqualError(t, err, test.expectedErr.Error()) 1069 } else { 1070 b, err := utils.ReadFile("golangci-lint.tar.gz") 1071 assert.NoError(t, err) 1072 assert.Equal(t, []byte("content"), b) 1073 b, err = utils.ReadFile(filepath.Join(golangciLintDir, "golangci-lint")) 1074 assert.NoError(t, err) 1075 assert.Equal(t, []byte("test content"), b) 1076 } 1077 }) 1078 } 1079 } 1080 1081 func Test_gitConfigurationForPrivateModules(t *testing.T) { 1082 type args struct { 1083 privateMod string 1084 token string 1085 } 1086 type expectations struct { 1087 commandsExecuted [][]string 1088 } 1089 tests := []struct { 1090 name string 1091 args args 1092 1093 expected expectations 1094 }{ 1095 { 1096 name: "with one private module", 1097 args: args{ 1098 privateMod: "example.com/*", 1099 token: "mytoken", 1100 }, 1101 expected: expectations{ 1102 commandsExecuted: [][]string{ 1103 {"git", "config", "--global", "url.https://mytoken@example.com.insteadOf", "https://example.com"}, 1104 }, 1105 }, 1106 }, 1107 { 1108 name: "with multiple private modules", 1109 args: args{ 1110 privateMod: "example.com/*,test.com/*", 1111 token: "mytoken", 1112 }, 1113 expected: expectations{ 1114 commandsExecuted: [][]string{ 1115 {"git", "config", "--global", "url.https://mytoken@example.com.insteadOf", "https://example.com"}, 1116 {"git", "config", "--global", "url.https://mytoken@test.com.insteadOf", "https://test.com"}, 1117 }, 1118 }, 1119 }, 1120 } 1121 for _, tt := range tests { 1122 t.Run(tt.name, func(t *testing.T) { 1123 utils := newGolangBuildTestsUtils() 1124 1125 err := gitConfigurationForPrivateModules(tt.args.privateMod, tt.args.token, utils) 1126 1127 if assert.NoError(t, err) { 1128 for i, expectedCommand := range tt.expected.commandsExecuted { 1129 assert.Equal(t, expectedCommand[0], utils.Calls[i].Exec) 1130 assert.Equal(t, expectedCommand[1:], utils.Calls[i].Params) 1131 } 1132 } 1133 }) 1134 } 1135 }