You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	feat: add validation for sbom generated by gradle (#5522)
This commit is contained in:
		| @@ -235,6 +235,33 @@ func createBOM(config *gradleExecuteBuildOptions, utils gradleExecuteBuildUtils) | ||||
| 		log.Entry().WithError(err).Errorf("failed to create BOM: %v", err) | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	// Validate generated SBOMs | ||||
| 	bomFilename := gradleBomFilename + ".xml" | ||||
| 	err = utils.WalkDir(rootPath, func(path string, d fs.DirEntry, err error) error { | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		if d.IsDir() { | ||||
| 			return nil | ||||
| 		} | ||||
| 		if strings.HasSuffix(path, bomFilename) { | ||||
| 			log.Entry().Infof("Validating generated SBOM: %s", path) | ||||
|  | ||||
| 			if err := piperutils.ValidateCycloneDX14(path); err != nil { | ||||
| 				log.Entry().Warnf("SBOM validation failed: %v", err) | ||||
| 			} else { | ||||
| 				purl := piperutils.GetPurl(path) | ||||
| 				log.Entry().Infof("SBOM validation passed") | ||||
| 				log.Entry().Infof("SBOM PURL: %s", purl) | ||||
| 			} | ||||
| 		} | ||||
| 		return nil | ||||
| 	}) | ||||
| 	if err != nil { | ||||
| 		log.Entry().Warnf("Failed to walk directory for SBOM validation: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -12,6 +12,7 @@ import ( | ||||
| 	"github.com/pkg/errors" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/config" | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperenv" | ||||
| ) | ||||
| @@ -43,6 +44,9 @@ func (d isDirEntryMock) Info() (fs.FileInfo, error) { | ||||
|  | ||||
| func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 	pipelineEnv := &gradleExecuteBuildCommonPipelineEnvironment{} | ||||
| 	SetConfigOptions(ConfigCommandOptions{ | ||||
| 		OpenFile: config.OpenPiperFile, | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("failed case - build.gradle isn't present", func(t *testing.T) { | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| @@ -61,9 +65,13 @@ func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success case - only build", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			return nil // No BOM files | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 			FilesMock:      &mock.FilesMock{}, | ||||
| 			Filepath:       walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		options := &gradleExecuteBuildOptions{ | ||||
| @@ -79,9 +87,13 @@ func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success case - build with flags", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			return nil // No BOM files | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 			FilesMock:      &mock.FilesMock{}, | ||||
| 			Filepath:       walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		options := &gradleExecuteBuildOptions{ | ||||
| @@ -98,11 +110,24 @@ func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success case - bom creation", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			var dirMock isDirEntryMock = func() bool { | ||||
| 				return false | ||||
| 			} | ||||
| 			// Simulate finding a BOM file | ||||
| 			return fn(filepath.Join("path", "to", "build", "reports", "bom-gradle.xml"), dirMock, nil) | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 			FilesMock:      &mock.FilesMock{}, | ||||
| 			Filepath:       walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		// Add a valid BOM file for validation | ||||
| 		utils.FilesMock.AddFile(filepath.Join("path", "to", "build", "reports", "bom-gradle.xml"), []byte(`<?xml version="1.0" encoding="UTF-8"?> | ||||
| <bom xmlns="http://cyclonedx.org/schema/bom/1.4" version="1"> | ||||
|   <components/> | ||||
| </bom>`)) | ||||
| 		options := &gradleExecuteBuildOptions{ | ||||
| 			Path:       "path/to", | ||||
| 			Task:       "build", | ||||
| @@ -153,9 +178,13 @@ func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success case - build using wrapper", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			return nil // No BOM files | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 			FilesMock:      &mock.FilesMock{}, | ||||
| 			Filepath:       walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		utils.FilesMock.AddFile("gradlew", []byte{}) | ||||
| @@ -172,11 +201,15 @@ func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("failed case - build", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			return nil // No BOM files | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{ | ||||
| 				ShouldFailOnCommand: map[string]error{"gradle build -p path/to": errors.New("failed to build")}, | ||||
| 			}, | ||||
| 			FilesMock: &mock.FilesMock{}, | ||||
| 			Filepath:  walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		options := &gradleExecuteBuildOptions{ | ||||
| @@ -191,11 +224,15 @@ func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("failed case - build with flags", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			return nil // No BOM files | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{ | ||||
| 				ShouldFailOnCommand: map[string]error{"gradle clean build -x test -p path/to": errors.New("failed to build with flags")}, | ||||
| 			}, | ||||
| 			FilesMock: &mock.FilesMock{}, | ||||
| 			Filepath:  walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		options := &gradleExecuteBuildOptions{ | ||||
| @@ -211,11 +248,15 @@ func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("failed case - bom creation", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			return nil // No BOM files (build failed before creation) | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{ | ||||
| 				ShouldFailOnCommand: map[string]error{"./gradlew cyclonedxBom -p path/to --init-script initScript.gradle.tmp": errors.New("failed to create bom")}, | ||||
| 			}, | ||||
| 			FilesMock: &mock.FilesMock{}, | ||||
| 			Filepath:  walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		utils.FilesMock.AddFile("gradlew", []byte{}) | ||||
| @@ -232,11 +273,15 @@ func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("failed case - publish artifacts", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			return nil // No module files | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{ | ||||
| 				ShouldFailOnCommand: map[string]error{"./gradlew publish -p path/to --init-script initScript.gradle.tmp": errors.New("failed to publish artifacts")}, | ||||
| 			}, | ||||
| 			FilesMock: &mock.FilesMock{}, | ||||
| 			Filepath:  walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		utils.FilesMock.AddFile("gradlew", []byte{}) | ||||
| @@ -251,6 +296,70 @@ func TestRunGradleExecuteBuild(t *testing.T) { | ||||
| 		assert.Error(t, err) | ||||
| 		assert.Contains(t, err.Error(), "failed to publish artifacts") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success case - bom creation with multiple modules", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			var dirMock isDirEntryMock = func() bool { | ||||
| 				return false | ||||
| 			} | ||||
| 			// Simulate finding multiple BOM files from different modules | ||||
| 			_ = fn(filepath.Join("module1", "build", "reports", "bom-gradle.xml"), dirMock, nil) | ||||
| 			_ = fn(filepath.Join("module2", "build", "reports", "bom-gradle.xml"), dirMock, nil) | ||||
| 			return nil | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 			FilesMock:      &mock.FilesMock{}, | ||||
| 			Filepath:       walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		// Add valid BOM files for both modules | ||||
| 		validBOM := []byte(`<?xml version="1.0" encoding="UTF-8"?> | ||||
| <bom xmlns="http://cyclonedx.org/schema/bom/1.4" version="1"> | ||||
|   <components/> | ||||
| </bom>`) | ||||
| 		utils.FilesMock.AddFile(filepath.Join("module1", "build", "reports", "bom-gradle.xml"), validBOM) | ||||
| 		utils.FilesMock.AddFile(filepath.Join("module2", "build", "reports", "bom-gradle.xml"), validBOM) | ||||
| 		options := &gradleExecuteBuildOptions{ | ||||
| 			Path:       "path/to", | ||||
| 			Task:       "build", | ||||
| 			UseWrapper: false, | ||||
| 			CreateBOM:  true, | ||||
| 		} | ||||
|  | ||||
| 		err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, 3, len(utils.Calls)) | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success case - bom creation with invalid BOM (validation warns but doesn't fail)", func(t *testing.T) { | ||||
| 		var walkDir WalkDirFunc = func(root string, fn fs.WalkDirFunc) error { | ||||
| 			var dirMock isDirEntryMock = func() bool { | ||||
| 				return false | ||||
| 			} | ||||
| 			// Simulate finding an invalid BOM file | ||||
| 			return fn(filepath.Join("path", "to", "build", "reports", "bom-gradle.xml"), dirMock, nil) | ||||
| 		} | ||||
| 		utils := gradleExecuteBuildMockUtils{ | ||||
| 			ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 			FilesMock:      &mock.FilesMock{}, | ||||
| 			Filepath:       walkDir, | ||||
| 		} | ||||
| 		utils.FilesMock.AddFile("path/to/build.gradle", []byte{}) | ||||
| 		// Add an invalid BOM file | ||||
| 		utils.FilesMock.AddFile(filepath.Join("path", "to", "build", "reports", "bom-gradle.xml"), []byte(`invalid xml content`)) | ||||
| 		options := &gradleExecuteBuildOptions{ | ||||
| 			Path:       "path/to", | ||||
| 			Task:       "build", | ||||
| 			UseWrapper: false, | ||||
| 			CreateBOM:  true, | ||||
| 		} | ||||
|  | ||||
| 		// Should not fail even with invalid BOM (validation only warns) | ||||
| 		err := runGradleExecuteBuild(options, nil, utils, pipelineEnv) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, 3, len(utils.Calls)) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func TestGetPublishedArtifactsNames(t *testing.T) { | ||||
|   | ||||
| @@ -9,46 +9,43 @@ package main | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/docker/docker/api/types/container" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"github.com/testcontainers/testcontainers-go" | ||||
| 	"github.com/testcontainers/testcontainers-go/exec" | ||||
| ) | ||||
|  | ||||
| const DOCKER_IMAGE_GRADLE = "gradle:6-jdk11-alpine" | ||||
|  | ||||
| func TestGradleIntegrationExecuteBuildJavaProjectBOMCreationUsingWrapper(t *testing.T) { | ||||
| 	// t.Parallel() | ||||
| 	t.Parallel() | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	pwd, err := os.Getwd() | ||||
| 	assert.NoError(t, err, "Getting current working directory failed.") | ||||
| 	pwd = filepath.Dir(pwd) | ||||
|  | ||||
| 	// using custom createTmpDir function to avoid issues with symlinks on Docker for Mac | ||||
| 	tempDir, err := createTmpDir(t) | ||||
| 	assert.NoError(t, err, "Error when creating temp dir") | ||||
|  | ||||
| 	err = copyDir(filepath.Join(pwd, "integration", "testdata", "TestGradleIntegration", "java-project"), tempDir) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Failed to copy test project.") | ||||
| 	} | ||||
|  | ||||
| 	//workaround to use test script util it is possible to set workdir for Exec call | ||||
| 	testScript := fmt.Sprintf(`#!/bin/sh | ||||
| cd /test | ||||
| /piperbin/piper gradleExecuteBuild >test-log.txt 2>&1 | ||||
| `) | ||||
| 	os.WriteFile(filepath.Join(tempDir, "runPiper.sh"), []byte(testScript), 0700) | ||||
|  | ||||
| 	reqNode := testcontainers.ContainerRequest{ | ||||
| 		Image: "adoptopenjdk/openjdk11:jdk-11.0.11_9-alpine", | ||||
| 		Image: DOCKER_IMAGE_GRADLE, | ||||
| 		Cmd:   []string{"tail", "-f"}, | ||||
| 		Mounts: testcontainers.Mounts( | ||||
| 			testcontainers.BindMount(pwd, "/piperbin"), | ||||
| 			testcontainers.BindMount(tempDir, "/test"), | ||||
| 		), | ||||
| 		Files: []testcontainers.ContainerFile{ | ||||
| 			{ | ||||
| 				HostFilePath:      filepath.Join(pwd, "integration", "testdata", "TestGradleIntegration", "java-project"), | ||||
| 				ContainerFilePath: "/", | ||||
| 				FileMode:          0755, | ||||
| 			}, | ||||
| 		}, | ||||
| 		HostConfigModifier: func(hc *container.HostConfig) { | ||||
| 			hc.Binds = []string{ | ||||
| 				fmt.Sprintf("%s:/piperbin", pwd), | ||||
| 			} | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	nodeContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ | ||||
| @@ -57,71 +54,55 @@ cd /test | ||||
| 	}) | ||||
| 	require.NoError(t, err) | ||||
|  | ||||
| 	code, _, err := nodeContainer.Exec(ctx, []string{"sh", "/test/runPiper.sh"}) | ||||
| 	code, reader, err := nodeContainer.Exec(ctx, []string{"/piperbin/piper", "gradleExecuteBuild"}, exec.WithWorkingDir("/java-project")) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, 0, code) | ||||
|  | ||||
| 	content, err := os.ReadFile(filepath.Join(tempDir, "/test-log.txt")) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Could not read test-log.txt.", err) | ||||
| 	} | ||||
| 	output := string(content) | ||||
| 	outputBytes, err := io.ReadAll(reader) | ||||
| 	assert.NoError(t, err) | ||||
| 	output := string(outputBytes) | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - running command: ./gradlew tasks") | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - running command: ./gradlew cyclonedxBom --init-script initScript.gradle.tmp") | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - running command: ./gradlew build") | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - BUILD SUCCESSFUL") | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - SUCCESS") | ||||
| 	assert.Contains(t, output, "Validating generated SBOM:") | ||||
| 	assert.Contains(t, output, "SBOM validation passed") | ||||
| 	assert.Contains(t, output, "SBOM PURL:") | ||||
|  | ||||
| 	//workaround to use test script util it is possible to set workdir for Exec call | ||||
| 	testScript = fmt.Sprintf(`#!/bin/sh | ||||
| cd /test | ||||
| ls -l ./build/reports/ >files-list.txt 2>&1 | ||||
| `) | ||||
| 	os.WriteFile(filepath.Join(tempDir, "runPiper.sh"), []byte(testScript), 0700) | ||||
|  | ||||
| 	code, _, err = nodeContainer.Exec(ctx, []string{"sh", "/test/runPiper.sh"}) | ||||
| 	code, reader, err = nodeContainer.Exec(ctx, []string{"ls", "-l", "./build/reports/"}, exec.WithWorkingDir("/java-project")) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, 0, code) | ||||
|  | ||||
| 	content, err = os.ReadFile(filepath.Join(tempDir, "/files-list.txt")) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Could not read files-list.txt.", err) | ||||
| 	} | ||||
| 	output = string(content) | ||||
| 	assert.Contains(t, output, "bom-gradle.xml") | ||||
| 	lsOutputBytes, err := io.ReadAll(reader) | ||||
| 	assert.NoError(t, err) | ||||
| 	lsOutput := string(lsOutputBytes) | ||||
| 	assert.Contains(t, lsOutput, "bom-gradle.xml") | ||||
| } | ||||
|  | ||||
| func TestGradleIntegrationExecuteBuildJavaProjectWithBomPlugin(t *testing.T) { | ||||
| 	// t.Parallel() | ||||
| 	t.Parallel() | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	pwd, err := os.Getwd() | ||||
| 	assert.NoError(t, err, "Getting current working directory failed.") | ||||
| 	pwd = filepath.Dir(pwd) | ||||
|  | ||||
| 	// using custom createTmpDir function to avoid issues with symlinks on Docker for Mac | ||||
| 	tempDir, err := createTmpDir(t) | ||||
| 	assert.NoError(t, err, "Error when creating temp dir") | ||||
|  | ||||
| 	err = copyDir(filepath.Join(pwd, "integration", "testdata", "TestGradleIntegration", "java-project-with-bom-plugin"), tempDir) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Failed to copy test project.") | ||||
| 	} | ||||
|  | ||||
| 	//workaround to use test script util it is possible to set workdir for Exec call | ||||
| 	testScript := fmt.Sprintf(`#!/bin/sh | ||||
| cd /test | ||||
| /piperbin/piper gradleExecuteBuild >test-log.txt 2>&1 | ||||
| `) | ||||
| 	os.WriteFile(filepath.Join(tempDir, "runPiper.sh"), []byte(testScript), 0700) | ||||
|  | ||||
| 	reqNode := testcontainers.ContainerRequest{ | ||||
| 		Image: "gradle:6-jdk11-alpine", | ||||
| 		Image: DOCKER_IMAGE_GRADLE, | ||||
| 		Cmd:   []string{"tail", "-f"}, | ||||
| 		Mounts: testcontainers.Mounts( | ||||
| 			testcontainers.BindMount(pwd, "/piperbin"), | ||||
| 			testcontainers.BindMount(tempDir, "/test"), | ||||
| 		), | ||||
| 		Files: []testcontainers.ContainerFile{ | ||||
| 			{ | ||||
| 				HostFilePath:      filepath.Join(pwd, "integration", "testdata", "TestGradleIntegration", "java-project-with-bom-plugin"), | ||||
| 				ContainerFilePath: "/", | ||||
| 				FileMode:          0755, | ||||
| 			}, | ||||
| 		}, | ||||
| 		HostConfigModifier: func(hc *container.HostConfig) { | ||||
| 			hc.Binds = []string{ | ||||
| 				fmt.Sprintf("%s:/piperbin", pwd), | ||||
| 			} | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	nodeContainer, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ | ||||
| @@ -130,36 +111,28 @@ cd /test | ||||
| 	}) | ||||
| 	require.NoError(t, err) | ||||
|  | ||||
| 	code, _, err := nodeContainer.Exec(ctx, []string{"sh", "/test/runPiper.sh"}) | ||||
| 	code, reader, err := nodeContainer.Exec(ctx, []string{"/piperbin/piper", "gradleExecuteBuild"}, exec.WithWorkingDir("/java-project-with-bom-plugin")) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, 0, code) | ||||
|  | ||||
| 	content, err := os.ReadFile(filepath.Join(tempDir, "/test-log.txt")) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Could not read test-log.txt.", err) | ||||
| 	} | ||||
| 	output := string(content) | ||||
| 	outputBytes, err := io.ReadAll(reader) | ||||
| 	assert.NoError(t, err) | ||||
| 	output := string(outputBytes) | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - running command: gradle tasks") | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - running command: gradle cyclonedxBom") | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - running command: gradle build") | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - BUILD SUCCESSFUL") | ||||
| 	assert.Contains(t, output, "info  gradleExecuteBuild - SUCCESS") | ||||
| 	assert.Contains(t, output, "Validating generated SBOM:") | ||||
| 	assert.Contains(t, output, "SBOM validation passed") | ||||
| 	assert.Contains(t, output, "SBOM PURL:") | ||||
|  | ||||
| 	//workaround to use test script util it is possible to set workdir for Exec call | ||||
| 	testScript = fmt.Sprintf(`#!/bin/sh | ||||
| cd /test | ||||
| ls -l ./build/reports/ >files-list.txt 2>&1 | ||||
| `) | ||||
| 	os.WriteFile(filepath.Join(tempDir, "runPiper.sh"), []byte(testScript), 0700) | ||||
|  | ||||
| 	code, _, err = nodeContainer.Exec(ctx, []string{"sh", "/test/runPiper.sh"}) | ||||
| 	code, reader, err = nodeContainer.Exec(ctx, []string{"ls", "-l", "./build/reports/"}, exec.WithWorkingDir("/java-project-with-bom-plugin")) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, 0, code) | ||||
|  | ||||
| 	content, err = os.ReadFile(filepath.Join(tempDir, "/files-list.txt")) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Could not read files-list.txt.", err) | ||||
| 	} | ||||
| 	output = string(content) | ||||
| 	assert.Contains(t, output, "bom-gradle.xml") | ||||
| 	lsOutputBytes, err := io.ReadAll(reader) | ||||
| 	assert.NoError(t, err) | ||||
| 	lsOutput := string(lsOutputBytes) | ||||
| 	assert.Contains(t, lsOutput, "bom-gradle.xml") | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user