mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-01-30 05:59:39 +02:00
Merge remote-tracking branch 'origin/master' into docuGen
This commit is contained in:
commit
049dc95b1d
@ -1,11 +1,19 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"io"
|
||||
)
|
||||
|
||||
type execRunner interface {
|
||||
RunExecutable(e string, p ...string) error
|
||||
Dir(d string)
|
||||
Stdout(out io.Writer)
|
||||
Stderr(err io.Writer)
|
||||
}
|
||||
|
||||
type shellRunner interface {
|
||||
RunShell(s string, c string) error
|
||||
Dir(d string)
|
||||
Stdout(out io.Writer)
|
||||
Stderr(err io.Writer)
|
||||
}
|
||||
|
@ -11,8 +11,8 @@ func karmaExecuteTests(myKarmaExecuteTestsOptions karmaExecuteTestsOptions) erro
|
||||
c := command.Command{}
|
||||
// reroute command output to loging framework
|
||||
// also log stdout as Karma reports into it
|
||||
c.Stdout = log.Entry().Writer()
|
||||
c.Stderr = log.Entry().Writer()
|
||||
c.Stdout(log.Entry().Writer())
|
||||
c.Stderr(log.Entry().Writer())
|
||||
runKarma(myKarmaExecuteTestsOptions, &c)
|
||||
return nil
|
||||
}
|
||||
|
@ -13,8 +13,10 @@ import (
|
||||
)
|
||||
|
||||
type execMockRunner struct {
|
||||
dir []string
|
||||
calls []execCall
|
||||
dir []string
|
||||
calls []execCall
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
shouldFailWith error
|
||||
}
|
||||
|
||||
@ -24,8 +26,10 @@ type execCall struct {
|
||||
}
|
||||
|
||||
type shellMockRunner struct {
|
||||
dir string
|
||||
calls []string
|
||||
dir string
|
||||
calls []string
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
shouldFailWith error
|
||||
}
|
||||
|
||||
@ -42,6 +46,16 @@ func (m *execMockRunner) RunExecutable(e string, p ...string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m * execMockRunner) Stdout(out io.Writer) {
|
||||
m.stdout = out
|
||||
}
|
||||
|
||||
|
||||
func (m * execMockRunner) Stderr(err io.Writer) {
|
||||
m.stderr = err
|
||||
}
|
||||
|
||||
|
||||
func (m *shellMockRunner) Dir(d string) {
|
||||
m.dir = d
|
||||
}
|
||||
@ -56,6 +70,15 @@ func (m *shellMockRunner) RunShell(s string, c string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m * shellMockRunner) Stdout(out io.Writer) {
|
||||
m.stdout = out
|
||||
}
|
||||
|
||||
|
||||
func (m * shellMockRunner) Stderr(err io.Writer) {
|
||||
m.stderr = err
|
||||
}
|
||||
|
||||
type stepOptions struct {
|
||||
TestParam string `json:"testParam,omitempty"`
|
||||
}
|
||||
|
@ -45,9 +45,11 @@ Following the convention for pipeline definitions, use a `Jenkinsfile` which res
|
||||
fioriOnCloudPlatformPipeline script:this
|
||||
```
|
||||
|
||||
`fioriOnCloudPlatform` is a so called _scenario step_ that wraps the [mtaBuild](https://sap.github.io/jenkins-library/steps/mtaBuild/) and the [neoDeploy](https://sap.github.io/jenkins-library/steps/neoDeploy/) steps.
|
||||
|
||||
### Configuration (`.pipeline/config.yml`)
|
||||
|
||||
This is a basic configuration example, which is also located in the sources of the project.
|
||||
This is a basic configuration example, which is also located in the sources of the project. The configuration corresponds to the steps wrapped in `fioriOnCloudPlatformPipeline`.
|
||||
|
||||
```yaml
|
||||
steps:
|
||||
|
@ -14,8 +14,8 @@ import (
|
||||
// Command defines the information required for executing a call to any executable
|
||||
type Command struct {
|
||||
dir string
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
stdout io.Writer
|
||||
stderr io.Writer
|
||||
}
|
||||
|
||||
// Dir sets the working directory for the execution
|
||||
@ -23,13 +23,23 @@ func (c *Command) Dir(d string) {
|
||||
c.dir = d
|
||||
}
|
||||
|
||||
// Stdout ..
|
||||
func (c *Command) Stdout(stdout io.Writer) {
|
||||
c.stdout = stdout
|
||||
}
|
||||
|
||||
// Stderr ..
|
||||
func (c *Command) Stderr(stderr io.Writer) {
|
||||
c.stderr = stderr
|
||||
}
|
||||
|
||||
// ExecCommand defines how to execute os commands
|
||||
var ExecCommand = exec.Command
|
||||
|
||||
// RunShell runs the specified command on the shell
|
||||
func (c *Command) RunShell(shell, script string) error {
|
||||
|
||||
_out, _err := prepareOut(c.Stdout, c.Stderr)
|
||||
_out, _err := prepareOut(c.stdout, c.stderr)
|
||||
|
||||
cmd := ExecCommand(shell)
|
||||
|
||||
@ -47,7 +57,7 @@ func (c *Command) RunShell(shell, script string) error {
|
||||
// RunExecutable runs the specified executable with parameters
|
||||
func (c *Command) RunExecutable(executable string, params ...string) error {
|
||||
|
||||
_out, _err := prepareOut(c.Stdout, c.Stderr)
|
||||
_out, _err := prepareOut(c.stdout, c.stderr)
|
||||
|
||||
cmd := ExecCommand(executable, params...)
|
||||
|
||||
|
@ -26,7 +26,7 @@ func TestShellRun(t *testing.T) {
|
||||
o := new(bytes.Buffer)
|
||||
e := new(bytes.Buffer)
|
||||
|
||||
s := Command{Stdout: o, Stderr: e}
|
||||
s := Command{stdout: o, stderr: e}
|
||||
s.RunShell("/bin/bash", "myScript")
|
||||
|
||||
t.Run("success case", func(t *testing.T) {
|
||||
@ -54,7 +54,7 @@ func TestExecutableRun(t *testing.T) {
|
||||
o := new(bytes.Buffer)
|
||||
e := new(bytes.Buffer)
|
||||
|
||||
ex := Command{Stdout: o, Stderr: e}
|
||||
ex := Command{stdout: o, stderr: e}
|
||||
ex.RunExecutable("echo", []string{"foo bar", "baz"}...)
|
||||
|
||||
t.Run("success case", func(t *testing.T) {
|
||||
@ -78,7 +78,7 @@ func TestPrepareOut(t *testing.T) {
|
||||
|
||||
t.Run("os", func(t *testing.T) {
|
||||
s := Command{}
|
||||
_out, _err := prepareOut(s.Stdout, s.Stderr)
|
||||
_out, _err := prepareOut(s.stdout, s.stderr)
|
||||
|
||||
if _out != os.Stdout {
|
||||
t.Errorf("expected out to be os.Stdout")
|
||||
@ -92,8 +92,8 @@ func TestPrepareOut(t *testing.T) {
|
||||
t.Run("custom", func(t *testing.T) {
|
||||
o := bytes.NewBufferString("")
|
||||
e := bytes.NewBufferString("")
|
||||
s := Command{Stdout: o, Stderr: e}
|
||||
_out, _err := prepareOut(s.Stdout, s.Stderr)
|
||||
s := Command{stdout: o, stderr: e}
|
||||
_out, _err := prepareOut(s.stdout, s.stderr)
|
||||
|
||||
expectOut := "Test out"
|
||||
expectErr := "Test err"
|
||||
|
@ -89,6 +89,21 @@ type Container struct {
|
||||
Shell string `json:"shell"`
|
||||
WorkingDir string `json:"workingDir"`
|
||||
Conditions []Condition `json:"conditions,omitempty"`
|
||||
Options []Option `json:"options,omitempt"`
|
||||
//VolumeMounts []VolumeMount `json:"volumeMounts,omitempty"`
|
||||
}
|
||||
|
||||
// ToDo: Add the missing Volumes part to enable the volume mount completly
|
||||
// VolumeMount defines an mount path
|
||||
// type VolumeMount struct {
|
||||
// MountPath string `json:"mountPath"`
|
||||
// Name string `json:"name"`
|
||||
//}
|
||||
|
||||
// Option defines an docker option
|
||||
type Option struct {
|
||||
Name string `json:"name"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// EnvVar defines an environment variable
|
||||
@ -229,6 +244,8 @@ func (m *StepData) GetContextDefaults(stepName string) (io.ReadCloser, error) {
|
||||
p["dockerName"] = container.Name
|
||||
p["dockerPullImage"] = container.ImagePullPolicy != "Never"
|
||||
p["dockerWorkspace"] = container.WorkingDir
|
||||
p["dockerOptions"] = optionsAsStringSlice(container.Options)
|
||||
//p["dockerVolumeBind"] = volumeMountsAsStringSlice(container.VolumeMounts)
|
||||
|
||||
// Ready command not relevant for main runtime container so far
|
||||
//p[] = container.ReadyCommand
|
||||
@ -246,14 +263,12 @@ func (m *StepData) GetContextDefaults(stepName string) (io.ReadCloser, error) {
|
||||
root["sidecarPullImage"] = m.Spec.Sidecars[0].ImagePullPolicy != "Never"
|
||||
root["sidecarReadyCommand"] = m.Spec.Sidecars[0].ReadyCommand
|
||||
root["sidecarWorkspace"] = m.Spec.Sidecars[0].WorkingDir
|
||||
root["sidecarOptions"] = optionsAsStringSlice(m.Spec.Sidecars[0].Options)
|
||||
//root["sidecarVolumeBind"] = volumeMountsAsStringSlice(m.Spec.Sidecars[0].VolumeMounts)
|
||||
}
|
||||
|
||||
// not filled for now since this is not relevant in Kubernetes case
|
||||
//p["dockerOptions"] = container.
|
||||
//p["dockerVolumeBind"] = container.
|
||||
//root["containerPortMappings"] = m.Spec.Sidecars[0].
|
||||
//root["sidecarOptions"] = m.Spec.Sidecars[0].
|
||||
//root["sidecarVolumeBind"] = m.Spec.Sidecars[0].
|
||||
|
||||
if len(m.Spec.Inputs.Resources) > 0 {
|
||||
keys := []string{}
|
||||
@ -310,3 +325,20 @@ func envVarsAsStringSlice(envVars []EnvVar) []string {
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
func optionsAsStringSlice(options []Option) []string {
|
||||
e := []string{}
|
||||
for _, v := range options {
|
||||
e = append(e, fmt.Sprintf("%v %v", v.Name, v.Value))
|
||||
}
|
||||
return e
|
||||
}
|
||||
|
||||
//ToDo: Enable this when the Volumes part is also implemented
|
||||
//func volumeMountsAsStringSlice(volumeMounts []VolumeMount) []string {
|
||||
// e := []string{}
|
||||
// for _, v := range volumeMounts {
|
||||
// e = append(e, fmt.Sprintf("%v:%v", v.Name, v.MountPath))
|
||||
// }
|
||||
// return e
|
||||
//}
|
||||
|
@ -338,6 +338,14 @@ func TestGetContextDefaults(t *testing.T) {
|
||||
Image: "testImage:tag",
|
||||
Shell: "/bin/bash",
|
||||
WorkingDir: "/test/dir",
|
||||
Options: []Option{
|
||||
{Name: "opt1", Value: "optValue1"},
|
||||
{Name: "opt2", Value: "optValue2"},
|
||||
},
|
||||
//VolumeMounts: []VolumeMount{
|
||||
// {MountPath: "mp1", Name: "mn1"},
|
||||
// {MountPath: "mp2", Name: "mn2"},
|
||||
//},
|
||||
},
|
||||
},
|
||||
Sidecars: []Container{
|
||||
@ -352,6 +360,14 @@ func TestGetContextDefaults(t *testing.T) {
|
||||
ImagePullPolicy: "Never",
|
||||
ReadyCommand: "/sidecar/command",
|
||||
WorkingDir: "/sidecar/dir",
|
||||
Options: []Option{
|
||||
{Name: "opt3", Value: "optValue3"},
|
||||
{Name: "opt4", Value: "optValue4"},
|
||||
},
|
||||
//VolumeMounts: []VolumeMount{
|
||||
// {MountPath: "mp3", Name: "mn3"},
|
||||
// {MountPath: "mp4", Name: "mn4"},
|
||||
//},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -379,6 +395,8 @@ func TestGetContextDefaults(t *testing.T) {
|
||||
assert.Equal(t, "testcontainer", d.Defaults[0].Steps["testStep"]["dockerName"], "dockerName default not available")
|
||||
assert.Equal(t, true, d.Defaults[0].Steps["testStep"]["dockerPullImage"], "dockerPullImage default not available")
|
||||
assert.Equal(t, "/test/dir", d.Defaults[0].Steps["testStep"]["dockerWorkspace"], "dockerWorkspace default not available")
|
||||
assert.Equal(t, []interface{}{"opt1 optValue1", "opt2 optValue2"}, d.Defaults[0].Steps["testStep"]["dockerOptions"], "dockerOptions default not available")
|
||||
//assert.Equal(t, []interface{}{"mn1:mp1", "mn2:mp2"}, d.Defaults[0].Steps["testStep"]["dockerVolumeBind"], "dockerVolumeBind default not available")
|
||||
|
||||
assert.Equal(t, "/sidecar/command", d.Defaults[0].Steps["testStep"]["sidecarCommand"], "sidecarCommand default not available")
|
||||
assert.Equal(t, []interface{}{"env3=val3", "env4=val4"}, d.Defaults[0].Steps["testStep"]["sidecarEnvVars"], "sidecarEnvVars default not available")
|
||||
@ -387,6 +405,8 @@ func TestGetContextDefaults(t *testing.T) {
|
||||
assert.Equal(t, false, d.Defaults[0].Steps["testStep"]["sidecarPullImage"], "sidecarPullImage default not available")
|
||||
assert.Equal(t, "/sidecar/command", d.Defaults[0].Steps["testStep"]["sidecarReadyCommand"], "sidecarReadyCommand default not available")
|
||||
assert.Equal(t, "/sidecar/dir", d.Defaults[0].Steps["testStep"]["sidecarWorkspace"], "sidecarWorkspace default not available")
|
||||
assert.Equal(t, []interface{}{"opt3 optValue3", "opt4 optValue4"}, d.Defaults[0].Steps["testStep"]["sidecarOptions"], "sidecarOptions default not available")
|
||||
//assert.Equal(t, []interface{}{"mn3:mp3", "mn4:mp4"}, d.Defaults[0].Steps["testStep"]["sidecarVolumeBind"], "sidecarVolumeBind default not available")
|
||||
})
|
||||
|
||||
t.Run("Negative case", func(t *testing.T) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user