1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-01-20 05:19:40 +02:00

Use mavenExecute from go (#1388)

Also establish mavenExecute() via new JenkinsMavenExecuteRule in Groovy Unit Tests.

Co-authored-by: Stephan Aßmus <stephan.assmus@sap.com>
Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com>
This commit is contained in:
Daniel Kurzynski 2020-04-24 10:41:49 +02:00 committed by GitHub
parent b335387eac
commit 974327d16e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 606 additions and 362 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
.idea/
/bin
bin
.settings
logs
reports

View File

@ -2,6 +2,7 @@ package cmd
import (
"fmt"
sliceUtils "github.com/SAP/jenkins-library/pkg/piperutils"
"strings"
"github.com/SAP/jenkins-library/pkg/command"
@ -49,21 +50,12 @@ func addDetectArgs(args []string, config detectExecuteScanOptions) []string {
}
args = append(args, fmt.Sprintf("--detect.code.location.name=%v", codeLocation))
if sliceContains(config.Scanners, "signature") {
if sliceUtils.ContainsString(config.Scanners, "signature") {
args = append(args, fmt.Sprintf("--detect.blackduck.signature.scanner.paths=%v", strings.Join(config.ScanPaths, ",")))
}
if sliceContains(config.Scanners, "source") {
if sliceUtils.ContainsString(config.Scanners, "source") {
args = append(args, fmt.Sprintf("--detect.source.path=%v", config.ScanPaths[0]))
}
return args
}
func sliceContains(slice []string, find string) bool {
for _, elem := range slice {
if elem == find {
return true
}
}
return false
}

View File

@ -4,29 +4,40 @@ import (
"github.com/SAP/jenkins-library/pkg/command"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/maven"
sliceUtils "github.com/SAP/jenkins-library/pkg/piperutils"
"io/ioutil"
"github.com/SAP/jenkins-library/pkg/telemetry"
)
func mavenExecute(config mavenExecuteOptions, telemetryData *telemetry.CustomData) string {
c := command.Command{}
func mavenExecute(config mavenExecuteOptions, _ *telemetry.CustomData) {
runner := command.Command{}
err := runMavenExecute(config, &runner)
if err != nil {
log.Entry().WithError(err).Fatal("step execution failed")
}
}
func runMavenExecute(config mavenExecuteOptions, runner execRunner) error {
options := maven.ExecuteOptions{
PomPath: config.PomPath,
ProjectSettingsFile: config.ProjectSettingsFile,
GlobalSettingsFile: config.GlobalSettingsFile,
M2Path: config.M2Path,
Goals: config.Goals,
Defines: config.Defines,
Flags: config.Flags,
Goals: splitTrimAndDeDupParams(config.Goals),
Defines: splitTrimAndDeDupParams(config.Defines),
Flags: splitTrimAndDeDupParams(config.Flags),
LogSuccessfulMavenTransfers: config.LogSuccessfulMavenTransfers,
ReturnStdout: config.ReturnStdout,
}
output, err := maven.Execute(&options, &c)
if err != nil {
log.Entry().WithError(err).Fatal("step execution failed")
output, err := maven.Execute(&options, runner)
if err == nil && config.ReturnStdout {
err = ioutil.WriteFile(".pipeline/maven_output.txt", []byte(output), 0644)
}
return output
return err
}
func splitTrimAndDeDupParams(params []string) []string {
return sliceUtils.SplitTrimAndDeDup(params, " ")
}

View File

@ -32,6 +32,7 @@ func TestRunMavenStaticCodeChecks(t *testing.T) {
"-Dspotbugs.excludeFilterFile=excludeFilter.xml",
"-Dpmd.maxAllowedViolations=10",
"-Dpmd.failurePriority=2",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn",
"--batch-mode",
"com.github.spotbugs:spotbugs-maven-plugin:3.1.12:check",
"org.apache.maven.plugins:maven-pmd-plugin:3.13.0:check",

35
cmd/mavenExecute_test.go Normal file
View File

@ -0,0 +1,35 @@
package cmd
import (
"github.com/SAP/jenkins-library/pkg/mock"
"github.com/stretchr/testify/assert"
"testing"
)
func TestMavenExecute(t *testing.T) {
t.Run("mavenExecute should cleanup the parameters", func(t *testing.T) {
mockRunner := mock.ExecMockRunner{}
config := mavenExecuteOptions{
Flags: []string{"--errors --fail-fast "},
Defines: []string{" -DoutputFile=mvnDependencyTree.txt"},
Goals: []string{" dependency:tree"},
}
err := runMavenExecute(config, &mockRunner)
expectedParams := []string{
"--errors",
"--fail-fast",
"-DoutputFile=mvnDependencyTree.txt",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn",
"--batch-mode",
"dependency:tree",
}
assert.NoError(t, err)
assert.Equal(t, "mvn", mockRunner.Calls[0].Exec)
assert.Equal(t, expectedParams, mockRunner.Calls[0].Params)
})
}

View File

@ -378,7 +378,7 @@ func TestUploadArtifacts(t *testing.T) {
})
err := uploadArtifacts(&utils, &uploader, &options, false)
assert.EqualError(t, err, "uploading artifacts for ID 'some.id' failed: failed to run executable, command: '[mvn -Durl=http:// -DgroupId=my.group.id -Dversion=3.0 -DartifactId=some.id -Dfile=mta.yaml -Dpackaging=yaml -DgeneratePom=false -Dfiles=artifact.mtar -Dclassifiers= -Dtypes=yaml --batch-mode "+deployGoal+"]', error: failed")
assert.EqualError(t, err, "uploading artifacts for ID 'some.id' failed: failed to run executable, command: '[mvn -Durl=http:// -DgroupId=my.group.id -Dversion=3.0 -DartifactId=some.id -Dfile=mta.yaml -Dpackaging=yaml -DgeneratePom=false -Dfiles=artifact.mtar -Dclassifiers= -Dtypes=yaml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode "+deployGoal+"]', error: failed")
})
t.Run("Uploading bundle generates correct maven parameters", func(t *testing.T) {
utils := newMockUtilsBundle(false, true, false)
@ -411,6 +411,7 @@ func TestUploadArtifacts(t *testing.T) {
"-Dfiles=pom.yml",
"-Dclassifiers=",
"-Dtypes=pom",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn",
"--batch-mode",
deployGoal}
assert.Equal(t, len(expectedParameters1), len(utils.execRunner.Calls[0].Params))
@ -655,6 +656,7 @@ func TestUploadMavenProjects(t *testing.T) {
"-DartifactId=my-app",
"-Dfile=pom.xml",
"-Dpackaging=pom",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn",
"--batch-mode",
deployGoal}
assert.Equal(t, len(expectedParameters1), len(utils.execRunner.Calls[0].Params))
@ -670,6 +672,7 @@ func TestUploadMavenProjects(t *testing.T) {
"-Dfiles=application/target/final-artifact.war,application/target/final-artifact-classes.jar",
"-Dclassifiers=,classes",
"-Dtypes=war,jar",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn",
"--batch-mode",
deployGoal}
assert.Equal(t, len(expectedParameters2), len(utils.execRunner.Calls[1].Params))
@ -703,6 +706,7 @@ func TestUploadMavenProjects(t *testing.T) {
"-DrepositoryId=" + settingsServerID,
"-Dfile=pom.xml",
"-Dpackaging=pom",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn",
"--batch-mode",
deployGoal}
assert.Equal(t, len(expectedParameters1), len(utils.execRunner.Calls[0].Params))

View File

@ -4,9 +4,10 @@ import (
"bytes"
"fmt"
"io"
"net/http"
"strings"
"github.com/SAP/jenkins-library/pkg/http"
piperhttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/piperutils"
)
@ -30,6 +31,31 @@ type mavenExecRunner interface {
RunExecutable(e string, p ...string) error
}
type mavenUtils interface {
FileExists(path string) (bool, error)
DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error
}
type utilsBundle struct {
httpClient piperhttp.Client
fileUtils piperutils.Files
}
func newUtils() *utilsBundle {
return &utilsBundle{
httpClient: piperhttp.Client{},
fileUtils: piperutils.Files{},
}
}
func (u *utilsBundle) FileExists(path string) (bool, error) {
return u.fileUtils.FileExists(path)
}
func (u *utilsBundle) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error {
return u.httpClient.DownloadFile(url, filename, header, cookies)
}
const mavenExecutable = "mvn"
// Execute constructs a mvn command line from the given options, and uses the provided
@ -39,7 +65,7 @@ func Execute(options *ExecuteOptions, command mavenExecRunner) (string, error) {
command.Stdout(stdOut)
command.Stderr(log.Entry().Writer())
parameters, err := getParametersFromOptions(options, &http.Client{})
parameters, err := getParametersFromOptions(options, newUtils())
if err != nil {
return "", fmt.Errorf("failed to construct parameters from options: %w", err)
}
@ -89,23 +115,11 @@ func evaluateStdOut(config *ExecuteOptions) (*bytes.Buffer, io.Writer) {
return stdOutBuf, stdOut
}
func downloadSettingsIfURL(settingsFileOption, settingsFile string, client http.Downloader) (string, error) {
result := settingsFileOption
if strings.HasPrefix(settingsFileOption, "http:") || strings.HasPrefix(settingsFileOption, "https:") {
err := downloadSettingsFromURL(settingsFileOption, settingsFile, client)
if err != nil {
return "", err
}
result = settingsFile
}
return result, nil
}
func getParametersFromOptions(options *ExecuteOptions, client http.Downloader) ([]string, error) {
func getParametersFromOptions(options *ExecuteOptions, utils mavenUtils) ([]string, error) {
var parameters []string
if options.GlobalSettingsFile != "" {
globalSettingsFileName, err := downloadSettingsIfURL(options.GlobalSettingsFile, "globalSettings.xml", client)
globalSettingsFileName, err := downloadSettingsIfURL(options.GlobalSettingsFile, ".pipeline/mavenGlobalSettings.xml", utils)
if err != nil {
return nil, err
}
@ -113,7 +127,7 @@ func getParametersFromOptions(options *ExecuteOptions, client http.Downloader) (
}
if options.ProjectSettingsFile != "" {
projectSettingsFileName, err := downloadSettingsIfURL(options.ProjectSettingsFile, "projectSettings.xml", client)
projectSettingsFileName, err := downloadSettingsIfURL(options.ProjectSettingsFile, ".pipeline/mavenProjectSettings.xml", utils)
if err != nil {
return nil, err
}
@ -136,19 +150,36 @@ func getParametersFromOptions(options *ExecuteOptions, client http.Downloader) (
parameters = append(parameters, options.Defines...)
}
parameters = append(parameters, "--batch-mode")
if options.LogSuccessfulMavenTransfers {
if !options.LogSuccessfulMavenTransfers {
parameters = append(parameters, "-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn")
}
parameters = append(parameters, "--batch-mode")
parameters = append(parameters, options.Goals...)
return parameters, nil
}
func downloadSettingsIfURL(settingsFileOption, settingsFile string, utils mavenUtils) (string, error) {
result := settingsFileOption
if strings.HasPrefix(settingsFileOption, "http:") || strings.HasPrefix(settingsFileOption, "https:") {
err := downloadSettingsFromURL(settingsFileOption, settingsFile, utils)
if err != nil {
return "", err
}
result = settingsFile
}
return result, nil
}
// ToDo replace with pkg/maven/settings GetSettingsFile
func downloadSettingsFromURL(url, filename string, client http.Downloader) error {
err := client.DownloadFile(url, filename, nil, nil)
func downloadSettingsFromURL(url, filename string, utils mavenUtils) error {
exists, _ := utils.FileExists(filename)
if exists {
log.Entry().Infof("Not downloading maven settings file, because it already exists at '%s'", filename)
return nil
}
err := utils.DownloadFile(url, filename, nil, nil)
if err != nil {
return fmt.Errorf("failed to download maven settings from URL '%s' to file '%s': %w",
url, filename, err)
@ -157,12 +188,16 @@ func downloadSettingsFromURL(url, filename string, client http.Downloader) error
}
func GetTestModulesExcludes() []string {
return getTestModulesExcludes(newUtils())
}
func getTestModulesExcludes(utils mavenUtils) []string {
var excludes []string
exists, _ := piperutils.FileExists("unit-tests/pom.xml")
exists, _ := utils.FileExists("unit-tests/pom.xml")
if exists {
excludes = append(excludes, "-pl", "!unit-tests")
}
exists, _ = piperutils.FileExists("integration-tests/pom.xml")
exists, _ = utils.FileExists("integration-tests/pom.xml")
if exists {
excludes = append(excludes, "-pl", "!integration-tests")
}

View File

@ -2,6 +2,7 @@ package maven
import (
"errors"
"fmt"
"os"
"github.com/SAP/jenkins-library/pkg/mock"
@ -9,17 +10,17 @@ import (
"net/http"
"testing"
piperHttp "github.com/SAP/jenkins-library/pkg/http"
"github.com/stretchr/testify/assert"
)
type mockDownloader struct {
type mockUtils struct {
shouldFail bool
requestedUrls []string
requestedFiles []string
files map[string][]byte
}
func (m *mockDownloader) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error {
func (m *mockUtils) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error {
m.requestedUrls = append(m.requestedUrls, url)
m.requestedFiles = append(m.requestedFiles, filename)
if m.shouldFail {
@ -28,15 +29,25 @@ func (m *mockDownloader) DownloadFile(url, filename string, header http.Header,
return nil
}
func (m *mockDownloader) SetOptions(options piperHttp.ClientOptions) {
return
func (m *mockUtils) FileExists(path string) (bool, error) {
content := m.files[path]
if content == nil {
return false, fmt.Errorf("'%s': %w", path, os.ErrNotExist)
}
return true, nil
}
func newMockUtils(downloadShouldFail bool) mockUtils {
utils := mockUtils{shouldFail: downloadShouldFail}
utils.files = map[string][]byte{}
return utils
}
func TestExecute(t *testing.T) {
t.Run("should return stdOut", func(t *testing.T) {
expectedOutput := "mocked output"
execMockRunner := mock.ExecMockRunner{}
execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml --batch-mode": "mocked output"}
execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode": "mocked output"}
opts := ExecuteOptions{PomPath: "pom.xml", ReturnStdout: true}
mavenOutput, _ := Execute(&opts, &execMockRunner)
@ -46,7 +57,7 @@ func TestExecute(t *testing.T) {
t.Run("should not return stdOut", func(t *testing.T) {
expectedOutput := ""
execMockRunner := mock.ExecMockRunner{}
execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml --batch-mode": "mocked output"}
execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode": "mocked output"}
opts := ExecuteOptions{PomPath: "pom.xml", ReturnStdout: false}
mavenOutput, _ := Execute(&opts, &execMockRunner)
@ -54,12 +65,12 @@ func TestExecute(t *testing.T) {
assert.Equal(t, expectedOutput, mavenOutput)
})
t.Run("should log that command failed if executing maven failed", func(t *testing.T) {
execMockRunner := mock.ExecMockRunner{ShouldFailOnCommand: map[string]error{"mvn --file pom.xml --batch-mode": errors.New("error case")}}
execMockRunner := mock.ExecMockRunner{ShouldFailOnCommand: map[string]error{"mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode": errors.New("error case")}}
opts := ExecuteOptions{PomPath: "pom.xml", ReturnStdout: false}
output, err := Execute(&opts, &execMockRunner)
assert.EqualError(t, err, "failed to run executable, command: '[mvn --file pom.xml --batch-mode]', error: error case")
assert.EqualError(t, err, "failed to run executable, command: '[mvn --file pom.xml -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode]', error: error case")
assert.Equal(t, "", output)
})
t.Run("should have all configured parameters in the exec call", func(t *testing.T) {
@ -70,8 +81,7 @@ func TestExecute(t *testing.T) {
Flags: []string{"-q"}, LogSuccessfulMavenTransfers: true,
ReturnStdout: false}
expectedParameters := []string{"--global-settings", "anotherSettings.xml", "--settings", "settings.xml",
"-Dmaven.repo.local=.m2/", "--file", "pom.xml", "-q", "-Da=b", "--batch-mode",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn", "flatten", "install"}
"-Dmaven.repo.local=.m2/", "--file", "pom.xml", "-q", "-Da=b", "--batch-mode", "flatten", "install"}
mavenOutput, _ := Execute(&opts, &execMockRunner)
@ -84,7 +94,7 @@ func TestExecute(t *testing.T) {
func TestEvaluate(t *testing.T) {
t.Run("should evaluate expression", func(t *testing.T) {
execMockRunner := mock.ExecMockRunner{}
execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.groupId -DforceStdout -q --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "com.awesome"}
execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.groupId -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "com.awesome"}
result, err := Evaluate("pom.xml", "project.groupId", &execMockRunner)
if assert.NoError(t, err) {
@ -93,7 +103,7 @@ func TestEvaluate(t *testing.T) {
})
t.Run("should not evaluate expression", func(t *testing.T) {
execMockRunner := mock.ExecMockRunner{}
execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.groupId -DforceStdout -q --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "null object or invalid expression"}
execMockRunner.StdoutReturn = map[string]string{"mvn --file pom.xml -Dexpression=project.groupId -DforceStdout -q -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn --batch-mode org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate": "null object or invalid expression"}
result, err := Evaluate("pom.xml", "project.groupId", &execMockRunner)
if assert.EqualError(t, err, "expression 'project.groupId' in file 'pom.xml' could not be resolved") {
@ -104,52 +114,78 @@ func TestEvaluate(t *testing.T) {
func TestGetParameters(t *testing.T) {
t.Run("should resolve configured parameters and download the settings files", func(t *testing.T) {
mockClient := mockDownloader{shouldFail: false}
utils := newMockUtils(false)
opts := ExecuteOptions{PomPath: "pom.xml", GlobalSettingsFile: "https://mysettings.com", ProjectSettingsFile: "http://myprojectsettings.com", ReturnStdout: false}
expectedParameters := []string{"--global-settings", "globalSettings.xml", "--settings", "projectSettings.xml", "--file", "pom.xml", "--batch-mode"}
expectedParameters := []string{
"--global-settings", ".pipeline/mavenGlobalSettings.xml",
"--settings", ".pipeline/mavenProjectSettings.xml",
"--file", "pom.xml",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn",
"--batch-mode"}
parameters, err := getParametersFromOptions(&opts, &mockClient)
parameters, err := getParametersFromOptions(&opts, &utils)
if assert.NoError(t, err) {
assert.Equal(t, len(expectedParameters), len(parameters))
assert.Equal(t, expectedParameters, parameters)
if assert.Equal(t, 2, len(mockClient.requestedUrls)) {
assert.Equal(t, "https://mysettings.com", mockClient.requestedUrls[0])
assert.Equal(t, "globalSettings.xml", mockClient.requestedFiles[0])
assert.Equal(t, "http://myprojectsettings.com", mockClient.requestedUrls[1])
assert.Equal(t, "projectSettings.xml", mockClient.requestedFiles[1])
if assert.Equal(t, 2, len(utils.requestedUrls)) {
assert.Equal(t, "https://mysettings.com", utils.requestedUrls[0])
assert.Equal(t, ".pipeline/mavenGlobalSettings.xml", utils.requestedFiles[0])
assert.Equal(t, "http://myprojectsettings.com", utils.requestedUrls[1])
assert.Equal(t, ".pipeline/mavenProjectSettings.xml", utils.requestedFiles[1])
}
}
})
t.Run("should resolve configured parameters and not download existing settings files", func(t *testing.T) {
utils := newMockUtils(false)
utils.files[".pipeline/mavenGlobalSettings.xml"] = []byte("dummyContent")
utils.files[".pipeline/mavenProjectSettings.xml"] = []byte("dummyContent")
opts := ExecuteOptions{PomPath: "pom.xml", GlobalSettingsFile: "https://mysettings.com", ProjectSettingsFile: "http://myprojectsettings.com", ReturnStdout: false}
expectedParameters := []string{
"--global-settings", ".pipeline/mavenGlobalSettings.xml",
"--settings", ".pipeline/mavenProjectSettings.xml",
"--file", "pom.xml",
"-Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn",
"--batch-mode"}
parameters, err := getParametersFromOptions(&opts, &utils)
if assert.NoError(t, err) {
assert.Equal(t, len(expectedParameters), len(parameters))
assert.Equal(t, expectedParameters, parameters)
assert.Equal(t, 0, len(utils.requestedUrls))
}
})
}
func TestDownloadSettingsFromURL(t *testing.T) {
t.Run("should pass if download is successful", func(t *testing.T) {
mockClient := mockDownloader{shouldFail: false}
err := downloadSettingsFromURL("anyURL", "settings.xml", &mockClient)
utils := newMockUtils(false)
err := downloadSettingsFromURL("anyURL", "settings.xml", &utils)
assert.NoError(t, err)
})
t.Run("should fail if download fails", func(t *testing.T) {
mockClient := mockDownloader{shouldFail: true}
err := downloadSettingsFromURL("anyURL", "settings.xml", &mockClient)
utils := newMockUtils(true)
err := downloadSettingsFromURL("anyURL", "settings.xml", &utils)
assert.EqualError(t, err, "failed to download maven settings from URL 'anyURL' to file 'settings.xml': something happened")
})
}
func TestGetTestModulesExcludes(t *testing.T) {
t.Run("Should return excludes for unit- and integration-tests", func(t *testing.T) {
currentDir, err := os.Getwd()
if err != nil {
t.Fatal("Failed to get current working directory")
}
defer os.Chdir(currentDir)
err = os.Chdir("../../test/resources/maven")
if err != nil {
t.Fatal("Failed to change to test directory")
}
utils := newMockUtils(false)
utils.files["unit-tests/pom.xml"] = []byte("dummyPomContent")
utils.files["integration-tests/pom.xml"] = []byte("dummyPomContent")
expected := []string{"-pl", "!unit-tests", "-pl", "!integration-tests"}
modulesExcludes := GetTestModulesExcludes()
modulesExcludes := getTestModulesExcludes(&utils)
assert.Equal(t, expected, modulesExcludes)
})
t.Run("Should not return excludes for unit- and integration-tests", func(t *testing.T) {
utils := newMockUtils(false)
var expected []string
modulesExcludes := getTestModulesExcludes(&utils)
assert.Equal(t, expected, modulesExcludes)
})
}

View File

@ -55,7 +55,7 @@ func GetSettingsFile(settingsFileType SettingsFileType, src string, fileUtils pi
}
} else {
// for sake os symetry it would be better to use a file protocol prefix here (file:)
// for sake os symmetry it would be better to use a file protocol prefix here (file:)
parent := filepath.Dir(dest)

View File

@ -4,7 +4,7 @@ import (
"strings"
)
//ContainsInt check wether the element is part of the slice
//ContainsInt check whether the element is part of the slice
func ContainsInt(s []int, e int) bool {
for _, a := range s {
if a == e {
@ -14,6 +14,16 @@ func ContainsInt(s []int, e int) bool {
return false
}
//ContainsString check whether the element is part of the slice
func ContainsString(s []string, e string) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}
//Prefix adds a prefix to each element of the slice
func Prefix(in []string, prefix string) []string {
return _prefix(in, prefix, true)
@ -43,3 +53,21 @@ func Trim(in []string) (out []string) {
}
return
}
// SplitTrimAndDeDup iterates over the strings in the given slice and splits each on the provided separator.
// Each resulting sub-string is then a separate entry in the returned array. Duplicate and empty entries are eliminated.
func SplitTrimAndDeDup(in []string, separator string) (out []string) {
if len(in) == 0 {
return in
}
for _, entry := range in {
entryParts := strings.Split(entry, separator)
for _, part := range entryParts {
part = strings.TrimSpace(part)
if part != "" && !ContainsString(out, part) {
out = append(out, part)
}
}
}
return
}

View File

@ -8,13 +8,25 @@ import (
func TestContainsInt(t *testing.T) {
var intList []int
assert.Equal(t, false, ContainsInt(intList, 4), "False expected but returned true")
assert.Equal(t, false, ContainsInt(intList, 4))
intList = append(intList, 1, 2, 3, 4, 5, 6, 20)
assert.Equal(t, true, ContainsInt(intList, 20), "True expected but returned false")
assert.Equal(t, true, ContainsInt(intList, 1), "True expected but returned false")
assert.Equal(t, true, ContainsInt(intList, 4), "True expected but returned false")
assert.Equal(t, false, ContainsInt(intList, 13), "False expected but returned true")
assert.Equal(t, true, ContainsInt(intList, 20))
assert.Equal(t, true, ContainsInt(intList, 1))
assert.Equal(t, true, ContainsInt(intList, 4))
assert.Equal(t, false, ContainsInt(intList, 13))
}
func TestContainsString(t *testing.T) {
var stringList []string
assert.False(t, ContainsString(stringList, "test"))
assert.False(t, ContainsString(stringList, ""))
stringList = append(stringList, "", "foo", "bar", "foo")
assert.True(t, ContainsString(stringList, ""))
assert.True(t, ContainsString(stringList, "bar"))
assert.True(t, ContainsString(stringList, "foo"))
assert.False(t, ContainsString(stringList, "baz"))
}
func TestPrefix(t *testing.T) {
@ -51,3 +63,39 @@ func TestTrim(t *testing.T) {
assert.Contains(t, s, "apple")
assert.Contains(t, s, "mango")
}
func TestSplitTrimAndDeDup(t *testing.T) {
t.Run("Separator is not space", func(t *testing.T) {
// init
s := []string{" a", "", "-a-b --c ", "d-e", "f", " f", ""}
// test
s = SplitTrimAndDeDup(s, "-")
// assert
assert.Equal(t, []string{"a", "b", "c", "d", "e", "f"}, s)
})
t.Run("Separator is space", func(t *testing.T) {
// init
s := []string{" a", " a b c ", "d e", "f", "f ", ""}
// test
s = SplitTrimAndDeDup(s, " ")
// assert
assert.Equal(t, []string{"a", "b", "c", "d", "e", "f"}, s)
})
t.Run("Separator is multi-char", func(t *testing.T) {
// init
s := []string{" a", " a** b**c ", "**d **e", "f**", "f ", ""}
// test
s = SplitTrimAndDeDup(s, "**")
// assert
assert.Equal(t, []string{"a", "b", "c", "d", "e", "f"}, s)
})
t.Run("Separator is empty string", func(t *testing.T) {
// init
s := []string{" a", " a bc ", "d e", "f", "f ", ""}
// test
s = SplitTrimAndDeDup(s, "")
// assert
// If "sep" is empty, underlying strings.Split() splits after each UTF-8 char sequence.
assert.Equal(t, []string{"a", "b", "c", "d", "e", "f"}, s)
})
}

View File

@ -12,6 +12,7 @@ import util.JenkinsCredentialsRule
import util.JenkinsDockerExecuteRule
import util.JenkinsEnvironmentRule
import util.JenkinsLoggingRule
import util.JenkinsMavenExecuteRule
import util.JenkinsReadMavenPomRule
import util.JenkinsReadYamlRule
import util.JenkinsShellCallRule
@ -52,6 +53,7 @@ class ArtifactSetVersionTest extends BasePiperTest {
private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this)
private JenkinsLoggingRule loggingRule = new JenkinsLoggingRule(this)
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
private JenkinsMavenExecuteRule mvnExecuteRule = new JenkinsMavenExecuteRule(this)
private JenkinsWriteFileRule writeFileRule = new JenkinsWriteFileRule(this)
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
private JenkinsEnvironmentRule environmentRule = new JenkinsEnvironmentRule(this)
@ -70,6 +72,7 @@ class ArtifactSetVersionTest extends BasePiperTest {
.around(stepRule)
.around(jenkinsCredentialsRule)
.around(environmentRule)
.around(mvnExecuteRule)
@Before
void init() throws Throwable {
@ -84,8 +87,18 @@ class ArtifactSetVersionTest extends BasePiperTest {
return closure()
})
shellRule.setReturnValue("mvn --file 'pom.xml' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.version -DforceStdout -q", version)
shellRule.setReturnValue("mvn --file 'snapshot/pom.xml' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.version", version)
mvnExecuteRule.setReturnValue([
'pomPath': 'pom.xml',
'goals': 'org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate',
'defines': '-Dexpression=project.version -DforceStdout -q',
], version)
mvnExecuteRule.setReturnValue([
'pomPath': 'snapshot/pom.xml',
'goals': 'org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate',
'defines': '-Dexpression=project.version -DforceStdout -q',
], version)
shellRule.setReturnValue("date --utc +'%Y%m%d%H%M%S'", '20180101010203')
shellRule.setReturnValue('git diff --quiet HEAD', 0)
@ -99,16 +112,20 @@ class ArtifactSetVersionTest extends BasePiperTest {
assertEquals('1.2.3-20180101010203_testCommitId', environmentRule.env.getArtifactVersion())
assertEquals('testCommitId', environmentRule.env.getGitCommitId())
assertThat(shellRule.shell, hasItem("mvn --file 'pom.xml' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn org.codehaus.mojo:versions-maven-plugin:2.7:set -DnewVersion=1.2.3-20180101010203_testCommitId -DgenerateBackupPoms=false"))
assertThat(shellRule.shell.join(), stringContainsInOrder([
"git add .",
"git commit -m 'update version 1.2.3-20180101010203_testCommitId'",
'git tag build_1.2.3-20180101010203_testCommitId',
'git push myGitSshUrl build_1.2.3-20180101010203_testCommitId',
]
))
}
assertEquals(new JenkinsMavenExecuteRule.Execution([
pomPath: 'pom.xml',
goals: 'org.codehaus.mojo:versions-maven-plugin:2.7:set',
defines: '-DnewVersion=1.2.3-20180101010203_testCommitId -DgenerateBackupPoms=false'
]), mvnExecuteRule.executions[1])
assertThat(shellRule.shell.join(), stringContainsInOrder([
"git add .",
"git commit -m 'update version 1.2.3-20180101010203_testCommitId'",
'git tag build_1.2.3-20180101010203_testCommitId',
'git push myGitSshUrl build_1.2.3-20180101010203_testCommitId',
]
))
}
@Test
void testVersioningNoPush() {
@ -119,8 +136,8 @@ class ArtifactSetVersionTest extends BasePiperTest {
buildTool: 'maven',
gitPushMode: 'NONE')
assertThat(loggingRule.log, containsString('Git push to remote has been skipped.'))
assertThat(((Iterable)shellRule.shell).join(), not(containsString('push')))
assertThat(loggingRule.log, containsString('Git push to remote has been skipped.'))
assertThat(((Iterable)shellRule.shell).join(), not(containsString('push')))
}
@Test
@ -139,14 +156,18 @@ class ArtifactSetVersionTest extends BasePiperTest {
// closer version checks already performed in test 'testVersioningPushViaSSH', focusing on
// GIT related assertions here
assertThat(shellRule.shell, hasItem("mvn --file 'pom.xml' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn org.codehaus.mojo:versions-maven-plugin:2.7:set -DnewVersion=1.2.3-20180101010203_testCommitId -DgenerateBackupPoms=false"))
assertEquals(new JenkinsMavenExecuteRule.Execution([
pomPath: 'pom.xml',
goals: 'org.codehaus.mojo:versions-maven-plugin:2.7:set',
defines: '-DnewVersion=1.2.3-20180101010203_testCommitId -DgenerateBackupPoms=false'
]), mvnExecuteRule.executions[1])
assertThat(((Iterable)shellRule.shell).join(), stringContainsInOrder([
"git add .",
"git commit -m 'update version 1.2.3-20180101010203_testCommitId'",
'git tag build_1.2.3-20180101010203_testCommitId',
'git push https://me:topSecret@example.org/myGitRepo build_1.2.3-20180101010203_testCommitId',
]
))
"git add .",
"git commit -m 'update version 1.2.3-20180101010203_testCommitId'",
'git tag build_1.2.3-20180101010203_testCommitId',
'git push https://me:topSecret@example.org/myGitRepo build_1.2.3-20180101010203_testCommitId',
]
))
}
@Test
@ -214,12 +235,12 @@ class ArtifactSetVersionTest extends BasePiperTest {
// GIT related assertions here
assertThat(((Iterable)shellRule.shell).join(), stringContainsInOrder([
"git add .",
"git commit -m 'update version 1.2.3-20180101010203_testCommitId'",
'git tag build_1.2.3-20180101010203_testCommitId',
'#!/bin/bash -e git push --quiet https://me:top%40Secret@example.org/myGitRepo build_1.2.3-20180101010203_testCommitId &>/dev/null',
]
))
"git add .",
"git commit -m 'update version 1.2.3-20180101010203_testCommitId'",
'git tag build_1.2.3-20180101010203_testCommitId',
'#!/bin/bash -e git push --quiet https://me:top%40Secret@example.org/myGitRepo build_1.2.3-20180101010203_testCommitId &>/dev/null',
]
))
}
@ -246,12 +267,12 @@ class ArtifactSetVersionTest extends BasePiperTest {
// GIT related assertions here
assertThat(((Iterable)shellRule.shell).join(), stringContainsInOrder([
"git add .",
"git commit -m 'update version 1.2.3-20180101010203_testCommitId'",
'git tag build_1.2.3-20180101010203_testCommitId',
'#!/bin/bash -e git push --quiet https://me:top%40Secret@example.org/myGitRepo build_1.2.3-20180101010203_testCommitId &>/dev/null',
]
))
"git add .",
"git commit -m 'update version 1.2.3-20180101010203_testCommitId'",
'git tag build_1.2.3-20180101010203_testCommitId',
'#!/bin/bash -e git push --quiet https://me:top%40Secret@example.org/myGitRepo build_1.2.3-20180101010203_testCommitId &>/dev/null',
]
))
}
@Test
@ -259,7 +280,11 @@ class ArtifactSetVersionTest extends BasePiperTest {
stepRule.step.artifactSetVersion(script: stepRule.step, juStabGitUtils: gitUtils, buildTool: 'maven', commitVersion: false)
assertEquals('1.2.3-20180101010203_testCommitId', environmentRule.env.getArtifactVersion())
assertThat(shellRule.shell, hasItem("mvn --file 'pom.xml' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn org.codehaus.mojo:versions-maven-plugin:2.7:set -DnewVersion=1.2.3-20180101010203_testCommitId -DgenerateBackupPoms=false"))
assertEquals(new JenkinsMavenExecuteRule.Execution([
pomPath: 'pom.xml',
goals: 'org.codehaus.mojo:versions-maven-plugin:2.7:set',
defines: '-DnewVersion=1.2.3-20180101010203_testCommitId -DgenerateBackupPoms=false'
]), mvnExecuteRule.executions[1])
assertThat(shellRule.shell, not(hasItem(containsString('commit'))))
}

View File

@ -58,7 +58,6 @@ public class CommonStepsTest extends BasePiperTest{
'prepareDefaultValues',
'setupCommonPipelineEnvironment',
'buildSetResult',
'mavenBuild',
'mavenExecuteStaticCodeChecks',
'cloudFoundryCreateServiceKey'
]
@ -132,10 +131,10 @@ public class CommonStepsTest extends BasePiperTest{
'xsDeploy', //implementing new golang pattern without fields
'cloudFoundryDeleteService', //implementing new golang pattern without fields
'cloudFoundryCreateServiceKey', //implementing new golang pattern without fields
'mavenBuild', //implementing new golang pattern without fields
'mavenExecute', //implementing new golang pattern without fields
'mavenExecuteStaticCodeChecks', //implementing new golang pattern without fields
'nexusUpload', //implementing new golang pattern without fields
'mavenBuild', //implementing new golang pattern without fields
'mavenExecuteStaticCodeChecks', //implementing new golang pattern without fields
'piperPipelineStageArtifactDeployment', //stage without step flags
'sonarExecuteScan', //implementing new golang pattern without fields
]

View File

@ -1,110 +1,122 @@
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.rules.ExpectedException
import org.junit.rules.RuleChain
import util.BasePiperTest
import util.JenkinsDockerExecuteRule
import util.JenkinsCredentialsRule
import util.JenkinsFileExistsRule
import util.JenkinsMavenExecuteRule
import util.JenkinsReadJsonRule
import util.JenkinsReadYamlRule
import util.JenkinsShellCallRule
import util.JenkinsStepRule
import util.JenkinsWriteFileRule
import util.Rules
import static org.hamcrest.Matchers.allOf
import static org.hamcrest.Matchers.containsString
import static org.hamcrest.Matchers.not
import static org.junit.Assert.assertEquals
import static org.hamcrest.Matchers.*
import static org.junit.Assert.assertThat
import static org.junit.Assert.assertTrue
class MavenExecuteTest extends BasePiperTest {
private ExpectedException exception = ExpectedException.none()
Map dockerParameters
private JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this)
private JenkinsCredentialsRule credentialsRule = new JenkinsCredentialsRule(this)
private JenkinsShellCallRule shellCallRule = new JenkinsShellCallRule(this)
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
private JenkinsWriteFileRule writeFileRule = new JenkinsWriteFileRule(this)
private JenkinsFileExistsRule fileExistsRule = new JenkinsFileExistsRule(this, [])
private List withEnvArgs = []
@Rule
public RuleChain ruleChain = Rules
public RuleChain rules = Rules
.getCommonRules(this)
.around(exception)
.around(new JenkinsReadYamlRule(this))
.around(dockerExecuteRule)
.around(shellRule)
.around(credentialsRule)
.around(new JenkinsReadJsonRule(this))
.around(shellCallRule)
.around(stepRule)
.around(writeFileRule)
.around(fileExistsRule)
@Test
void testExecuteBasicMavenCommand() throws Exception {
stepRule.step.mavenExecute(script: nullScript, goals: 'clean install')
assertEquals('maven:3.5-jdk-7', dockerExecuteRule.dockerParams.dockerImage)
assert shellRule.shell[0] == 'mvn --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn clean install'
@Before
void init() {
helper.registerAllowedMethod("withEnv", [List, Closure], { arguments, closure ->
arguments.each {arg ->
withEnvArgs.add(arg.toString())
}
return closure()
})
credentialsRule.withCredentials('idOfCxCredential', "admin", "admin123")
shellCallRule.setReturnValue(
'./piper getConfig --contextConfig --stepMetadata \'.pipeline/tmp/metadata/mavenExecute.yaml\'',
'{"credentialsId": "idOfCxCredential", "verbose": false}'
)
}
@Test
void testExecuteBasicMavenCommandWithDownloadLogsEnabled() throws Exception {
stepRule.step.mavenExecute(script: nullScript, goals: 'clean install', logSuccessfulMavenTransfers: true)
assertEquals('maven:3.5-jdk-7', dockerExecuteRule.dockerParams.dockerImage)
assert shellRule.shell[0] == 'mvn --batch-mode clean install'
}
@Test
void testExecuteMavenCommandWithParameter() throws Exception {
void testExecute() {
stepRule.step.mavenExecute(
juStabUtils: utils,
jenkinsUtilsStub: jenkinsUtils,
testParam: "This is test content",
script: nullScript,
dockerImage: 'maven:3.5-jdk-8-alpine',
goals: 'clean install',
globalSettingsFile: 'globalSettingsFile.xml',
projectSettingsFile: 'projectSettingsFile.xml',
pomPath: 'pom.xml',
flags: '-o',
m2Path: 'm2Path',
defines: '-Dmaven.tests.skip=true')
assertEquals('maven:3.5-jdk-8-alpine', dockerExecuteRule.dockerParams.dockerImage)
String mvnCommand = "mvn --global-settings 'globalSettingsFile.xml' -Dmaven.repo.local='m2Path' --settings 'projectSettingsFile.xml' --file 'pom.xml' -o --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn clean install -Dmaven.tests.skip=true"
assertTrue(shellRule.shell.contains(mvnCommand))
)
// asserts
assertThat(writeFileRule.files['.pipeline/tmp/metadata/mavenExecute.yaml'], containsString('name: mavenExecute'))
assertThat(withEnvArgs[0], allOf(startsWith('PIPER_parametersJSON'),
containsString('"testParam":"This is test content"')))
assertThat(shellCallRule.shell[1], is('./piper mavenExecute'))
}
@Test
void testMavenCommandForwardsDockerOptions() throws Exception {
stepRule.step.mavenExecute(script: nullScript, goals: 'clean install')
assertEquals('maven:3.5-jdk-7', dockerExecuteRule.dockerParams.dockerImage)
void testOutputIsReturned() {
// init
String outputFile = '.pipeline/maven_output.txt'
String expectedOutput = 'the output'
fileExistsRule.registerExistingFile(outputFile)
helper.registerAllowedMethod('readFile', [String], {file ->
if (file == outputFile) {
return expectedOutput
}
return ''
})
assertEquals('mvn --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn clean install', shellRule.shell[0])
// test
String receivedOutput = stepRule.step.mavenExecute(
juStabUtils: utils,
jenkinsUtilsStub: jenkinsUtils,
script: nullScript,
returnStdout: true,
)
// asserts
assertThat(receivedOutput, is(expectedOutput))
}
@Test
void testMavenCommandWithShortBatchModeFlag() throws Exception {
stepRule.step.mavenExecute(script: nullScript, goals: 'clean install', flags: '-B')
assertEquals('maven:3.5-jdk-7', dockerExecuteRule.dockerParams.dockerImage)
void testOutputIsMissing() {
// init
fileExistsRule.setExistingFiles([])
helper.registerAllowedMethod('readFile', [String], {file ->
return ''
})
String errorMessage = ''
helper.registerAllowedMethod('error', [String], {message ->
errorMessage = message
})
assertEquals('mvn -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn clean install', shellRule.shell[0])
}
// test
stepRule.step.mavenExecute(
juStabUtils: utils,
jenkinsUtilsStub: jenkinsUtils,
script: nullScript,
returnStdout: true,
)
@Test
void testMavenCommandWithFalsePositiveMinusBFlag() throws Exception {
stepRule.step.mavenExecute(script: nullScript, goals: 'clean install', flags: '-Blah')
assertEquals('maven:3.5-jdk-7', dockerExecuteRule.dockerParams.dockerImage)
assertThat(shellRule.shell[0],
allOf(containsString('-Blah'),
containsString('--batch-mode')))
}
@Test
void testMavenCommandWithBatchModeMultiline() throws Exception {
stepRule.step.mavenExecute(script: nullScript, goals: 'clean install', flags: ('''-B\\
|--show-version''' as CharSequence).stripMargin())
assertThat(shellRule.shell[0], not(containsString('--batch-mode')))
}
@Test
void testMavenExecuteReturnsStdout() {
shellRule.setReturnValue('mvn --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn clean install', "[INFO] BUILD SUCCESS")
String commandOutput = stepRule.step.mavenExecute(script: nullScript, goals: 'clean install', returnStdout: true)
assertEquals(commandOutput, '[INFO] BUILD SUCCESS')
// asserts
assertThat(errorMessage, containsString('Internal error. A text file with the contents of the maven output was expected'))
}
}

View File

@ -13,12 +13,9 @@ class NexusUploadTest extends BasePiperTest {
private ExpectedException exception = ExpectedException.none()
private JenkinsCredentialsRule credentialsRule = new JenkinsCredentialsRule(this)
private JenkinsReadJsonRule readJsonRule = new JenkinsReadJsonRule(this)
private JenkinsShellCallRule shellCallRule = new JenkinsShellCallRule(this)
private JenkinsStepRule stepRule = new JenkinsStepRule(this)
private JenkinsWriteFileRule writeFileRule = new JenkinsWriteFileRule(this)
private JenkinsFileExistsRule fileExistsRule = new JenkinsFileExistsRule(this, [])
//private JenkinsDockerExecuteRule dockerExecuteRule = new JenkinsDockerExecuteRule(this, [])
private List withEnvArgs = []
@ -28,23 +25,15 @@ class NexusUploadTest extends BasePiperTest {
.around(exception)
.around(new JenkinsReadYamlRule(this))
.around(credentialsRule)
.around(readJsonRule)
.around(new JenkinsReadJsonRule(this))
.around(shellCallRule)
.around(stepRule)
.around(writeFileRule)
.around(fileExistsRule)
// .around(dockerExecuteRule)
.around(new JenkinsFileExistsRule(this, []))
@Before
void init() {
helper.registerAllowedMethod('fileExists', [Map], {
return true
})
helper.registerAllowedMethod("readJSON", [Map], { m ->
if (m.file == 'nexusUpload_reports.json')
return [[target: "1234.pdf", mandatory: true]]
if (m.file == 'nexusUpload_links.json')
return []
if (m.text != null)
return new JsonSlurper().parseText(m.text)
})
@ -54,9 +43,6 @@ class NexusUploadTest extends BasePiperTest {
}
return closure()
})
// helper.registerAllowedMethod("dockerExecute", [Map, Closure], { map, closure ->
// // ignore
// })
credentialsRule.withCredentials('idOfCxCredential', "admin", "admin123")
shellCallRule.setReturnValue(
'./piper getConfig --contextConfig --stepMetadata \'.pipeline/tmp/metadata/nexusUpload.yaml\'',

View File

@ -6,9 +6,8 @@ import org.junit.Test
import org.junit.rules.RuleChain
import util.BasePiperTest
import util.JenkinsReadMavenPomRule
import util.JenkinsMavenExecuteRule
import util.JenkinsReadYamlRule
import util.JenkinsShellCallRule
import util.Rules
import static org.junit.Assert.assertEquals
@ -21,14 +20,13 @@ class MavenArtifactVersioningTest extends BasePiperTest{
MavenArtifactVersioning av
String version = '1.2.3'
JenkinsShellCallRule shellRule = new JenkinsShellCallRule(this)
JenkinsMavenExecuteRule mvnExecuteRule = new JenkinsMavenExecuteRule(this)
@Rule
public RuleChain ruleChain = Rules
.getCommonRules(this)
.around(new JenkinsReadYamlRule(this))
.around(shellRule)
.around(new JenkinsReadMavenPomRule(this, 'test/resources/versioning/MavenArtifactVersioning'))
.around(mvnExecuteRule)
@Before
void init() {
@ -40,8 +38,17 @@ class MavenArtifactVersioningTest extends BasePiperTest{
closure()
})
shellRule.setReturnValue("mvn --file 'pom.xml' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.version -DforceStdout -q", version)
shellRule.setReturnValue("mvn --file 'snapshot/pom.xml' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate -Dexpression=project.version -DforceStdout -q", version)
mvnExecuteRule.setReturnValue([
'pomPath': 'pom.xml',
'goals': 'org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate',
'defines': '-Dexpression=project.version -DforceStdout -q',
], version)
mvnExecuteRule.setReturnValue([
'pomPath': 'snapshot/pom.xml',
'goals': 'org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate',
'defines': '-Dexpression=project.version -DforceStdout -q',
], version)
}
@Test
@ -49,7 +56,18 @@ class MavenArtifactVersioningTest extends BasePiperTest{
av = new MavenArtifactVersioning(nullScript, [filePath: 'pom.xml'])
assertEquals(version, av.getVersion())
av.setVersion('1.2.3-20180101')
assertEquals('mvn --file \'pom.xml\' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn org.codehaus.mojo:versions-maven-plugin:2.7:set -DnewVersion=1.2.3-20180101 -DgenerateBackupPoms=false', shellRule.shell[1])
assertEquals(2, mvnExecuteRule.executions.size())
assertEquals(new JenkinsMavenExecuteRule.Execution([
pomPath: 'pom.xml',
goals: 'org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate',
defines: '-Dexpression=project.version -DforceStdout -q'
]), mvnExecuteRule.executions[0])
assertEquals(new JenkinsMavenExecuteRule.Execution([
pomPath: 'pom.xml',
goals: 'org.codehaus.mojo:versions-maven-plugin:2.7:set',
defines: '-DnewVersion=1.2.3-20180101 -DgenerateBackupPoms=false'
]), mvnExecuteRule.executions[1])
}
@Test
@ -57,6 +75,17 @@ class MavenArtifactVersioningTest extends BasePiperTest{
av = new MavenArtifactVersioning(nullScript, [filePath: 'snapshot/pom.xml'])
assertEquals('1.2.3', av.getVersion())
av.setVersion('1.2.3-20180101')
assertEquals('mvn --file \'snapshot/pom.xml\' --batch-mode -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn org.codehaus.mojo:versions-maven-plugin:2.7:set -DnewVersion=1.2.3-20180101 -DgenerateBackupPoms=false', shellRule.shell[1])
assertEquals(2, mvnExecuteRule.executions.size())
assertEquals(new JenkinsMavenExecuteRule.Execution([
pomPath: 'snapshot/pom.xml',
goals : 'org.apache.maven.plugins:maven-help-plugin:3.1.0:evaluate',
defines: '-Dexpression=project.version -DforceStdout -q'
]), mvnExecuteRule.executions[0])
assertEquals(new JenkinsMavenExecuteRule.Execution([
pomPath: 'snapshot/pom.xml',
goals : 'org.codehaus.mojo:versions-maven-plugin:2.7:set',
defines: '-DnewVersion=1.2.3-20180101 -DgenerateBackupPoms=false'
]), mvnExecuteRule.executions[1])
}
}

View File

@ -26,7 +26,13 @@ class JenkinsFileExistsRule implements TestRule {
JenkinsFileExistsRule registerExistingFile(String file) {
existingFiles.add(file)
return this
return this
}
JenkinsFileExistsRule setExistingFiles(List files) {
existingFiles.clear()
existingFiles.addAll(files)
return this
}
@Override

View File

@ -0,0 +1,111 @@
package util
import com.lesfurets.jenkins.unit.BasePipelineTest
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
class JenkinsMavenExecuteRule implements TestRule {
static class Execution {
final String pomPath
final List goals
final List defines
final List flags
Execution(Map parameters) {
this.pomPath = parameters.pomPath ?: 'pom.xml'
this.goals = asList(parameters.goals)
this.defines = asList(parameters.defines)
this.flags = asList(parameters.flags)
}
String toString() {
return "--file ${pomPath} : ${goals} : ${defines} : ${flags}"
}
@Override
int hashCode() {
return pomPath.hashCode() * goals.hashCode() * defines.hashCode() * flags.hashCode()
}
@Override
boolean equals(Object obj) {
if (obj == null || !obj instanceof Execution) {
return false
}
Execution other = (Execution) obj
return goals == other.goals && defines == other.defines && flags == other.flags
}
private List asList(def value) {
if (value instanceof List) {
return value as List
}
if (value instanceof CharSequence) {
return [ value ]
}
return []
}
}
final BasePipelineTest testInstance
List<Execution> executions = []
Map<String, String> returnValues = [:]
JenkinsMavenExecuteRule(BasePipelineTest testInstance) {
this.testInstance = testInstance
}
def setReturnValue(Map params, String value) {
returnValues.put(stringify(params), value)
}
def handleExecution(Map parameters) {
String params = stringify(parameters)
executions.add(new Execution(parameters))
def result = returnValues.get(params)
if (!result && parameters.returnStatus) {
result = 0
}
if (!parameters.returnStdout && !parameters.returnStatus) {
return
}
return result
}
@Override
Statement apply(Statement base, Description description) {
return statement(base)
}
private Statement statement(final Statement base) {
return new Statement() {
@Override
void evaluate() throws Throwable {
testInstance.helper.registerAllowedMethod("mavenExecute", [Map.class], {
map -> handleExecution(map)
})
base.evaluate()
}
}
}
private static String stringify(Map map) {
String params = ''
List keys = ['pomPath', 'goals', 'defines', 'flags']
for (String key : keys) {
if (params.length() > 0)
params += ' '
params += map.get(key)
}
return params.replaceAll(/\s+/," ").trim()
}
}

View File

@ -1,10 +1,5 @@
import com.sap.piper.PiperGoUtils
import com.sap.piper.Utils
import com.sap.piper.JenkinsUtils
import groovy.transform.Field
import static com.sap.piper.Prerequisites.checkScript
@Field String STEP_NAME = getClass().getName()
@Field String METADATA_FILE = 'metadata/checkmarx.yaml'

View File

@ -1,9 +1,5 @@
import com.sap.piper.PiperGoUtils
import com.sap.piper.Utils
import groovy.transform.Field
import static com.sap.piper.Prerequisites.checkScript
@Field String STEP_NAME = getClass().getName()
@Field String METADATA_FILE = 'metadata/kubernetesdeploy.yaml'

View File

@ -1,11 +1,14 @@
import com.sap.piper.DownloadCacheUtils
import groovy.transform.Field
import static com.sap.piper.Prerequisites.checkScript
@Field String METADATA_FILE = 'metadata/mavenBuild.yaml'
@Field String STEP_NAME = getClass().getName()
void call(Map parameters = [:]) {
List credentials = [ ]
parameters = DownloadCacheUtils.injectDownloadCacheInMavenParameters(parameters.script, parameters)
final script = checkScript(this, parameters) ?: this
parameters = DownloadCacheUtils.injectDownloadCacheInMavenParameters(script, parameters)
piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials)
}

View File

@ -1,139 +1,27 @@
import static com.sap.piper.Prerequisites.checkScript
import com.sap.piper.GenerateDocumentation
import com.sap.piper.ConfigurationHelper
import com.sap.piper.Utils
import com.sap.piper.DownloadCacheUtils
import groovy.transform.Field
import static com.sap.piper.Utils.downloadSettingsFromUrl
import static com.sap.piper.Prerequisites.checkScript
@Field def STEP_NAME = getClass().getName()
@Field String METADATA_FILE = 'metadata/mavenExecute.yaml'
@Field Set GENERAL_CONFIG_KEYS = []
@Field Set STEP_CONFIG_KEYS = [
/** @see dockerExecute */
'dockerImage',
/** Path or url to the mvn settings file that should be used as global settings file.*/
'globalSettingsFile',
/** Path or url to the mvn settings file that should be used as project settings file.*/
'projectSettingsFile',
/** Path to the pom file that should be used.*/
'pomPath',
/** Path to the location of the local repository that should be used.*/
'm2Path'
]
@Field Set PARAMETER_KEYS = STEP_CONFIG_KEYS.plus([
/** @see dockerExecute */
'dockerOptions',
/** Flags to provide when running mvn.*/
'flags',
/** Maven goals that should be executed.*/
'goals',
/** Additional properties.*/
'defines',
/**
* Configures maven to log successful downloads. This is set to `false` by default to reduce the noise in build logs.
* @possibleValues `true`, `false`
*/
'logSuccessfulMavenTransfers',
/**
* Returns the standard output of the maven command for further processing. By default stdout will be printed to the console but not returned by mavenExecute.
* @possibleValues `true`, `false`
*/
'returnStdout'
])
/**
* Executes a maven command inside a Docker container.
*/
@GenerateDocumentation
def call(Map parameters = [:]) {
final script = checkScript(this, parameters) ?: this
String commandOutput = ''
parameters = DownloadCacheUtils.injectDownloadCacheInMavenParameters(script, parameters)
// load default & individual configuration
Map configuration = ConfigurationHelper.newInstance(this)
.loadStepDefaults()
.mixinGeneralConfig(script.commonPipelineEnvironment, GENERAL_CONFIG_KEYS)
.mixinStepConfig(script.commonPipelineEnvironment, STEP_CONFIG_KEYS)
.mixinStageConfig(script.commonPipelineEnvironment, parameters.stageName ?: env.STAGE_NAME, STEP_CONFIG_KEYS)
.mixin(parameters, PARAMETER_KEYS)
.use()
List credentials = [ ]
piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials)
handlePipelineStepErrors(stepName: STEP_NAME, stepParameters: parameters) {
new Utils().pushToSWA([
step : STEP_NAME,
stepParamKey1: 'scriptMissing',
stepParam1 : parameters?.script == null
], configuration)
String command = "mvn"
String globalSettingsFile = configuration.globalSettingsFile?.trim()
if (globalSettingsFile) {
if (globalSettingsFile.startsWith("http")) {
globalSettingsFile = downloadSettingsFromUrl(this, globalSettingsFile, 'global-settings.xml')
}
command += " --global-settings '${globalSettingsFile}'"
}
String m2Path = configuration.m2Path
if (m2Path?.trim()) {
command += " -Dmaven.repo.local='${m2Path}'"
}
String projectSettingsFile = configuration.projectSettingsFile?.trim()
if (projectSettingsFile) {
if (projectSettingsFile.startsWith("http")) {
projectSettingsFile = downloadSettingsFromUrl(this, projectSettingsFile, 'project-settings.xml')
}
command += " --settings '${projectSettingsFile}'"
}
String pomPath = configuration.pomPath
if (pomPath?.trim()) {
command += " --file '${pomPath}'"
}
String mavenFlags = configuration.flags
if (mavenFlags?.trim()) {
command += " ${mavenFlags}"
}
// Always use Maven's batch mode
if (!(command =~ /--batch-mode|-B(?=\s)|-B\\|-B$/)) {
command += ' --batch-mode'
}
// Disable log for successful transfers by default. Note this requires the batch-mode flag.
final String disableSuccessfulMavenTransfersLogFlag = ' -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn'
if (!configuration.logSuccessfulMavenTransfers) {
if (!command.contains(disableSuccessfulMavenTransfersLogFlag)) {
command += disableSuccessfulMavenTransfersLogFlag
}
}
def mavenGoals = configuration.goals
if (mavenGoals?.trim()) {
command += " ${mavenGoals}"
}
def defines = configuration.defines
if (defines?.trim()) {
command += " ${defines}"
}
dockerExecute(script: script, dockerImage: configuration.dockerImage, dockerOptions: configuration.dockerOptions) {
if (configuration.returnStdout) {
commandOutput = sh(returnStdout: true, script: command)
} else {
sh command
}
String output = ''
if (parameters.returnStdout) {
String outputFile = '.pipeline/maven_output.txt'
if (!fileExists(outputFile)) {
error "[$STEP_NAME] Internal error. A text file with the contents of the maven output was expected " +
"but does not exist at '$outputFile'. " +
"Please file a ticket at https://github.com/SAP/jenkins-library/issues/new/choose"
}
output = readFile(outputFile)
}
if (configuration.returnStdout) {
return commandOutput
}
return output
}

View File

@ -2,7 +2,6 @@ import com.sap.piper.DownloadCacheUtils
import groovy.transform.Field
import static com.sap.piper.Prerequisites.checkScript
import static groovy.json.JsonOutput.toJson
@Field String STEP_NAME = getClass().getName()
@Field String METADATA_FILE = 'metadata/nexusUpload.yaml'

View File

@ -1,6 +1,7 @@
import com.sap.piper.BashUtils
import com.sap.piper.DefaultValueCache
import com.sap.piper.JenkinsUtils
import com.sap.piper.MapUtils
import com.sap.piper.PiperGoUtils
import com.sap.piper.Utils
@ -27,6 +28,10 @@ void call(Map parameters = [:], stepName, metadataFile, List credentialInfo, fai
writeFile(file: ".pipeline/tmp/${metadataFile}", text: libraryResource(metadataFile))
// When converting to JSON and back again, entries which had a 'null' value will now have a value
// of type 'net.sf.json.JSONNull', for which the Groovy Truth resolves to 'true' in for example if-conditions
stepParameters = MapUtils.pruneNulls(stepParameters)
withEnv([
"PIPER_parametersJSON=${groovy.json.JsonOutput.toJson(stepParameters)}",
//ToDo: check if parameters make it into docker image on JaaS