mirror of
https://github.com/SAP/jenkins-library.git
synced 2026-06-19 22:58:55 +02:00
chore: cleanup reporting & some incorrect file usage in tests (#3943)
* chore: cleanup reporting & some incorrect file usage in tests * cleanup interface * chore: remove comment * preserve error handling * Rename FileUtils.go to fileUtils.go * clean up formatting * chore: address static check findings * fix brittle test * chore: cleanup formatting
This commit is contained in:
@@ -16,19 +16,19 @@ import (
|
|||||||
func abapAddonAssemblyKitCheckPV(config abapAddonAssemblyKitCheckPVOptions, telemetryData *telemetry.CustomData, cpe *abapAddonAssemblyKitCheckPVCommonPipelineEnvironment) {
|
func abapAddonAssemblyKitCheckPV(config abapAddonAssemblyKitCheckPVOptions, telemetryData *telemetry.CustomData, cpe *abapAddonAssemblyKitCheckPVCommonPipelineEnvironment) {
|
||||||
utils := aakaas.NewAakBundle()
|
utils := aakaas.NewAakBundle()
|
||||||
// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end
|
// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end
|
||||||
if err := runAbapAddonAssemblyKitCheckPV(&config, telemetryData, &utils, cpe); err != nil {
|
if err := runAbapAddonAssemblyKitCheckPV(&config, telemetryData, utils, cpe); err != nil {
|
||||||
log.Entry().WithError(err).Fatal("step execution failed")
|
log.Entry().WithError(err).Fatal("step execution failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func runAbapAddonAssemblyKitCheckPV(config *abapAddonAssemblyKitCheckPVOptions, telemetryData *telemetry.CustomData, utils *aakaas.AakUtils, cpe *abapAddonAssemblyKitCheckPVCommonPipelineEnvironment) error {
|
func runAbapAddonAssemblyKitCheckPV(config *abapAddonAssemblyKitCheckPVOptions, telemetryData *telemetry.CustomData, utils aakaas.AakUtils, cpe *abapAddonAssemblyKitCheckPVCommonPipelineEnvironment) error {
|
||||||
|
|
||||||
conn := new(abapbuild.Connector)
|
conn := new(abapbuild.Connector)
|
||||||
if err := conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, *utils); err != nil {
|
if err := conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, utils); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Entry().Infof("Reading Product Version Information from addonDescriptor (aka addon.yml) file: %s", config.AddonDescriptorFileName)
|
log.Entry().Infof("Reading Product Version Information from addonDescriptor (aka addon.yml) file: %s", config.AddonDescriptorFileName)
|
||||||
addonDescriptor, err := (*utils).ReadAddonDescriptor(config.AddonDescriptorFileName)
|
addonDescriptor, err := utils.ReadAddonDescriptor(config.AddonDescriptorFileName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -57,8 +57,10 @@ func runAbapAddonAssemblyKitCheckPV(config *abapAddonAssemblyKitCheckPVOptions,
|
|||||||
var filesToPublish []piperutils.Path
|
var filesToPublish []piperutils.Path
|
||||||
log.Entry().Infof("Add %s to be published", config.AddonDescriptorFileName)
|
log.Entry().Infof("Add %s to be published", config.AddonDescriptorFileName)
|
||||||
filesToPublish = append(filesToPublish, piperutils.Path{Target: config.AddonDescriptorFileName, Name: "AddonDescriptor", Mandatory: true})
|
filesToPublish = append(filesToPublish, piperutils.Path{Target: config.AddonDescriptorFileName, Name: "AddonDescriptor", Mandatory: true})
|
||||||
log.Entry().Infof("Publsihing %v files", len(filesToPublish))
|
log.Entry().Infof("Publishing %v files", len(filesToPublish))
|
||||||
piperutils.PersistReportsAndLinks("abapAddonAssemblyKitCheckPV", "", filesToPublish, nil)
|
if err := piperutils.PersistReportsAndLinks("abapAddonAssemblyKitCheckPV", "", utils, filesToPublish, nil); err != nil {
|
||||||
|
log.Entry().WithError(err).Error("failed to persist report information")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ func TestCheckPVStep(t *testing.T) {
|
|||||||
config.Password = "dummyPassword"
|
config.Password = "dummyPassword"
|
||||||
t.Run("step success", func(t *testing.T) {
|
t.Run("step success", func(t *testing.T) {
|
||||||
config.AddonDescriptorFileName = "success"
|
config.AddonDescriptorFileName = "success"
|
||||||
err := runAbapAddonAssemblyKitCheckPV(&config, nil, &utils, &cpe)
|
err := runAbapAddonAssemblyKitCheckPV(&config, nil, utils, &cpe)
|
||||||
assert.NoError(t, err, "Did not expect error")
|
assert.NoError(t, err, "Did not expect error")
|
||||||
var addonDescriptorFinal abaputils.AddonDescriptor
|
var addonDescriptorFinal abaputils.AddonDescriptor
|
||||||
err = json.Unmarshal([]byte(cpe.abap.addonDescriptor), &addonDescriptorFinal)
|
err = json.Unmarshal([]byte(cpe.abap.addonDescriptor), &addonDescriptorFinal)
|
||||||
@@ -32,7 +32,7 @@ func TestCheckPVStep(t *testing.T) {
|
|||||||
})
|
})
|
||||||
t.Run("step error - in ReadAddonDescriptor", func(t *testing.T) {
|
t.Run("step error - in ReadAddonDescriptor", func(t *testing.T) {
|
||||||
config.AddonDescriptorFileName = "failing"
|
config.AddonDescriptorFileName = "failing"
|
||||||
err := runAbapAddonAssemblyKitCheckPV(&config, nil, &utils, &cpe)
|
err := runAbapAddonAssemblyKitCheckPV(&config, nil, utils, &cpe)
|
||||||
assert.Error(t, err, "Did expect error")
|
assert.Error(t, err, "Did expect error")
|
||||||
assert.Equal(t, err.Error(), "error in ReadAddonDescriptor")
|
assert.Equal(t, err.Error(), "error in ReadAddonDescriptor")
|
||||||
})
|
})
|
||||||
@@ -40,7 +40,7 @@ func TestCheckPVStep(t *testing.T) {
|
|||||||
config.AddonDescriptorFileName = "success"
|
config.AddonDescriptorFileName = "success"
|
||||||
bundle.SetBody("ErrorBody")
|
bundle.SetBody("ErrorBody")
|
||||||
bundle.SetError("error during validation")
|
bundle.SetError("error during validation")
|
||||||
err := runAbapAddonAssemblyKitCheckPV(&config, nil, &utils, &cpe)
|
err := runAbapAddonAssemblyKitCheckPV(&config, nil, utils, &cpe)
|
||||||
assert.Error(t, err, "Did expect error")
|
assert.Error(t, err, "Did expect error")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,13 +32,14 @@ func abapEnvironmentAssemblePackages(config abapEnvironmentAssemblePackagesOptio
|
|||||||
}
|
}
|
||||||
|
|
||||||
client := piperhttp.Client{}
|
client := piperhttp.Client{}
|
||||||
err := runAbapEnvironmentAssemblePackages(&config, telemetryData, &autils, &client, cpe)
|
utils := piperutils.Files{}
|
||||||
|
err := runAbapEnvironmentAssemblePackages(&config, telemetryData, &autils, &utils, &client, cpe)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Entry().WithError(err).Fatal("step execution failed")
|
log.Entry().WithError(err).Fatal("step execution failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runAbapEnvironmentAssemblePackages(config *abapEnvironmentAssemblePackagesOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client abapbuild.HTTPSendLoader, cpe *abapEnvironmentAssemblePackagesCommonPipelineEnvironment) error {
|
func runAbapEnvironmentAssemblePackages(config *abapEnvironmentAssemblePackagesOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, utils piperutils.FileUtils, client abapbuild.HTTPSendLoader, cpe *abapEnvironmentAssemblePackagesCommonPipelineEnvironment) error {
|
||||||
connBuild := new(abapbuild.Connector)
|
connBuild := new(abapbuild.Connector)
|
||||||
if errConBuild := initAssemblePackagesConnection(connBuild, config, com, client); errConBuild != nil {
|
if errConBuild := initAssemblePackagesConnection(connBuild, config, com, client); errConBuild != nil {
|
||||||
return errConBuild
|
return errConBuild
|
||||||
@@ -71,7 +72,7 @@ func runAbapEnvironmentAssemblePackages(config *abapEnvironmentAssemblePackagesO
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Entry().Infof("Publishing %v files", len(filesToPublish))
|
log.Entry().Infof("Publishing %v files", len(filesToPublish))
|
||||||
piperutils.PersistReportsAndLinks("abapEnvironmentAssemblePackages", "", filesToPublish, nil)
|
piperutils.PersistReportsAndLinks("abapEnvironmentAssemblePackages", "", utils, filesToPublish, nil)
|
||||||
|
|
||||||
var reposBackToCPE []abaputils.Repository
|
var reposBackToCPE []abaputils.Repository
|
||||||
for _, b := range builds {
|
for _, b := range builds {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
|
abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
|
||||||
"github.com/SAP/jenkins-library/pkg/abaputils"
|
"github.com/SAP/jenkins-library/pkg/abaputils"
|
||||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||||
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -83,26 +84,24 @@ func TestStep(t *testing.T) {
|
|||||||
cpe := &abapEnvironmentAssemblePackagesCommonPipelineEnvironment{}
|
cpe := &abapEnvironmentAssemblePackagesCommonPipelineEnvironment{}
|
||||||
|
|
||||||
t.Run("abapEnvironmentAssemblePackages: nothing to do", func(t *testing.T) {
|
t.Run("abapEnvironmentAssemblePackages: nothing to do", func(t *testing.T) {
|
||||||
|
|
||||||
config := &abapEnvironmentAssemblePackagesOptions{
|
config := &abapEnvironmentAssemblePackagesOptions{
|
||||||
AddonDescriptor: cpeAbapAddonDescriptorPackageLocked,
|
AddonDescriptor: cpeAbapAddonDescriptorPackageLocked,
|
||||||
MaxRuntimeInMinutes: 1,
|
MaxRuntimeInMinutes: 1,
|
||||||
PollIntervalsInMilliseconds: 1,
|
PollIntervalsInMilliseconds: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := runAbapEnvironmentAssemblePackages(config, nil, autils, &client, cpe)
|
err := runAbapEnvironmentAssemblePackages(config, nil, autils, &mock.FilesMock{}, &client, cpe)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, cpe.abap.addonDescriptor, `"InBuildScope":false`)
|
assert.Contains(t, cpe.abap.addonDescriptor, `"InBuildScope":false`)
|
||||||
})
|
})
|
||||||
t.Run("abapEnvironmentAssemblePackages: build", func(t *testing.T) {
|
t.Run("abapEnvironmentAssemblePackages: build", func(t *testing.T) {
|
||||||
|
|
||||||
config := &abapEnvironmentAssemblePackagesOptions{
|
config := &abapEnvironmentAssemblePackagesOptions{
|
||||||
AddonDescriptor: cpeAbapAddonDescriptorPackageReserved,
|
AddonDescriptor: cpeAbapAddonDescriptorPackageReserved,
|
||||||
MaxRuntimeInMinutes: 1,
|
MaxRuntimeInMinutes: 1,
|
||||||
PollIntervalsInMilliseconds: 1,
|
PollIntervalsInMilliseconds: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := runAbapEnvironmentAssemblePackages(config, nil, autils, &client, cpe)
|
err := runAbapEnvironmentAssemblePackages(config, nil, autils, &mock.FilesMock{}, &client, cpe)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, cpe.abap.addonDescriptor, `SAPK-001AAINITAPC1.SAR`)
|
assert.Contains(t, cpe.abap.addonDescriptor, `SAPK-001AAINITAPC1.SAR`)
|
||||||
assert.Contains(t, cpe.abap.addonDescriptor, `"InBuildScope":true`)
|
assert.Contains(t, cpe.abap.addonDescriptor, `"InBuildScope":true`)
|
||||||
|
|||||||
+25
-26
@@ -5,7 +5,6 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
|
abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
|
||||||
@@ -21,8 +20,8 @@ import (
|
|||||||
type abapEnvironmentBuildUtils interface {
|
type abapEnvironmentBuildUtils interface {
|
||||||
command.ExecRunner
|
command.ExecRunner
|
||||||
abaputils.Communication
|
abaputils.Communication
|
||||||
abapbuild.Publish
|
|
||||||
abapbuild.HTTPSendLoader
|
abapbuild.HTTPSendLoader
|
||||||
|
piperutils.FileUtils
|
||||||
getMaxRuntime() time.Duration
|
getMaxRuntime() time.Duration
|
||||||
getPollingInterval() time.Duration
|
getPollingInterval() time.Duration
|
||||||
publish()
|
publish()
|
||||||
@@ -32,6 +31,7 @@ type abapEnvironmentBuildUtilsBundle struct {
|
|||||||
*command.Command
|
*command.Command
|
||||||
*piperhttp.Client
|
*piperhttp.Client
|
||||||
*abaputils.AbapUtils
|
*abaputils.AbapUtils
|
||||||
|
*piperutils.Files
|
||||||
maxRuntime time.Duration
|
maxRuntime time.Duration
|
||||||
pollingInterval time.Duration
|
pollingInterval time.Duration
|
||||||
storePublish publish
|
storePublish publish
|
||||||
@@ -44,14 +44,14 @@ type publish struct {
|
|||||||
links []piperutils.Path
|
links []piperutils.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *publish) publish() {
|
func (p *publish) publish(utils piperutils.FileUtils) {
|
||||||
if p.stepName != "" {
|
if p.stepName != "" {
|
||||||
abapbuild.PersistReportsAndLinks(p.stepName, p.workspace, p.reports, p.links)
|
piperutils.PersistReportsAndLinks(p.stepName, p.workspace, utils, p.reports, p.links)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aEBUB *abapEnvironmentBuildUtilsBundle) publish() {
|
func (aEBUB *abapEnvironmentBuildUtilsBundle) publish() {
|
||||||
aEBUB.storePublish.publish()
|
aEBUB.storePublish.publish(aEBUB)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (aEBUB *abapEnvironmentBuildUtilsBundle) getMaxRuntime() time.Duration {
|
func (aEBUB *abapEnvironmentBuildUtilsBundle) getMaxRuntime() time.Duration {
|
||||||
@@ -63,7 +63,7 @@ func (aEBUB *abapEnvironmentBuildUtilsBundle) getPollingInterval() time.Duration
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (aEBUB *abapEnvironmentBuildUtilsBundle) PersistReportsAndLinks(stepName, workspace string, reports, links []piperutils.Path) {
|
func (aEBUB *abapEnvironmentBuildUtilsBundle) PersistReportsAndLinks(stepName, workspace string, reports, links []piperutils.Path) {
|
||||||
//abapbuild.PersistReportsAndLinks(stepName, workspace, reports, links)
|
// abapbuild.PersistReportsAndLinks(stepName, workspace, reports, links)
|
||||||
if aEBUB.storePublish.stepName == "" {
|
if aEBUB.storePublish.stepName == "" {
|
||||||
aEBUB.storePublish.stepName = stepName
|
aEBUB.storePublish.stepName = stepName
|
||||||
aEBUB.storePublish.workspace = workspace
|
aEBUB.storePublish.workspace = workspace
|
||||||
@@ -94,13 +94,12 @@ func newAbapEnvironmentBuildUtils(maxRuntime time.Duration, pollingInterval time
|
|||||||
|
|
||||||
func abapEnvironmentBuild(config abapEnvironmentBuildOptions, telemetryData *telemetry.CustomData, cpe *abapEnvironmentBuildCommonPipelineEnvironment) {
|
func abapEnvironmentBuild(config abapEnvironmentBuildOptions, telemetryData *telemetry.CustomData, cpe *abapEnvironmentBuildCommonPipelineEnvironment) {
|
||||||
utils := newAbapEnvironmentBuildUtils(time.Duration(config.MaxRuntimeInMinutes), time.Duration(config.PollingIntervalInSeconds))
|
utils := newAbapEnvironmentBuildUtils(time.Duration(config.MaxRuntimeInMinutes), time.Duration(config.PollingIntervalInSeconds))
|
||||||
if err := runAbapEnvironmentBuild(&config, telemetryData, &utils, cpe); err != nil {
|
if err := runAbapEnvironmentBuild(&config, telemetryData, utils, cpe); err != nil {
|
||||||
log.Entry().WithError(err).Fatal("step execution failed")
|
log.Entry().WithError(err).Fatal("step execution failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runAbapEnvironmentBuild(config *abapEnvironmentBuildOptions, telemetryData *telemetry.CustomData, utils *abapEnvironmentBuildUtils, cpe *abapEnvironmentBuildCommonPipelineEnvironment) error {
|
func runAbapEnvironmentBuild(config *abapEnvironmentBuildOptions, telemetryData *telemetry.CustomData, utils abapEnvironmentBuildUtils, cpe *abapEnvironmentBuildCommonPipelineEnvironment) error {
|
||||||
|
|
||||||
conn := new(abapbuild.Connector)
|
conn := new(abapbuild.Connector)
|
||||||
if err := initConnection(conn, config, utils); err != nil {
|
if err := initConnection(conn, config, utils); err != nil {
|
||||||
return errors.Wrap(err, "Connector initialization for communication with the ABAP system failed")
|
return errors.Wrap(err, "Connector initialization for communication with the ABAP system failed")
|
||||||
@@ -112,8 +111,8 @@ func runAbapEnvironmentBuild(config *abapEnvironmentBuildOptions, telemetryData
|
|||||||
}
|
}
|
||||||
|
|
||||||
finalValues, err := runBuilds(conn, config, utils, valuesList)
|
finalValues, err := runBuilds(conn, config, utils, valuesList)
|
||||||
//files should be published, even if an error occured
|
// files should be published, even if an error occured
|
||||||
(*utils).publish()
|
utils.publish()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -125,9 +124,9 @@ func runAbapEnvironmentBuild(config *abapEnvironmentBuildOptions, telemetryData
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func runBuilds(conn *abapbuild.Connector, config *abapEnvironmentBuildOptions, utils *abapEnvironmentBuildUtils, valuesList [][]abapbuild.Value) ([]abapbuild.Value, error) {
|
func runBuilds(conn *abapbuild.Connector, config *abapEnvironmentBuildOptions, utils abapEnvironmentBuildUtils, valuesList [][]abapbuild.Value) ([]abapbuild.Value, error) {
|
||||||
var finalValues []abapbuild.Value
|
var finalValues []abapbuild.Value
|
||||||
//No addonDescriptor involved
|
// No addonDescriptor involved
|
||||||
if len(valuesList) == 0 {
|
if len(valuesList) == 0 {
|
||||||
values, err := generateValuesOnlyFromConfig(config)
|
values, err := generateValuesOnlyFromConfig(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -138,7 +137,7 @@ func runBuilds(conn *abapbuild.Connector, config *abapEnvironmentBuildOptions, u
|
|||||||
return finalValues, errors.Wrap(err, "Error during execution of build framework")
|
return finalValues, errors.Wrap(err, "Error during execution of build framework")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Run several times for each repository in the addonDescriptor
|
// Run several times for each repository in the addonDescriptor
|
||||||
var errstrings []string
|
var errstrings []string
|
||||||
vE := valuesEvaluator{}
|
vE := valuesEvaluator{}
|
||||||
vE.m = make(map[string]string)
|
vE.m = make(map[string]string)
|
||||||
@@ -156,7 +155,7 @@ func runBuilds(conn *abapbuild.Connector, config *abapEnvironmentBuildOptions, u
|
|||||||
errstrings = append(errstrings, err.Error())
|
errstrings = append(errstrings, err.Error())
|
||||||
}
|
}
|
||||||
finalValuesForOneBuild = removeAddonDescriptorValues(finalValuesForOneBuild, values)
|
finalValuesForOneBuild = removeAddonDescriptorValues(finalValuesForOneBuild, values)
|
||||||
//This means: probably values are duplicated, but the first one wins -> perhaps change this in the future if needed
|
// This means: probably values are duplicated, but the first one wins -> perhaps change this in the future if needed
|
||||||
if err := vE.appendValuesIfNotPresent(finalValuesForOneBuild, false); err != nil {
|
if err := vE.appendValuesIfNotPresent(finalValuesForOneBuild, false); err != nil {
|
||||||
errstrings = append(errstrings, err.Error())
|
errstrings = append(errstrings, err.Error())
|
||||||
}
|
}
|
||||||
@@ -170,7 +169,7 @@ func runBuilds(conn *abapbuild.Connector, config *abapEnvironmentBuildOptions, u
|
|||||||
return finalValues, nil
|
return finalValues, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func initConnection(conn *abapbuild.Connector, config *abapEnvironmentBuildOptions, utils *abapEnvironmentBuildUtils) error {
|
func initConnection(conn *abapbuild.Connector, config *abapEnvironmentBuildOptions, utils abapEnvironmentBuildUtils) error {
|
||||||
var connConfig abapbuild.ConnectorConfiguration
|
var connConfig abapbuild.ConnectorConfiguration
|
||||||
connConfig.CfAPIEndpoint = config.CfAPIEndpoint
|
connConfig.CfAPIEndpoint = config.CfAPIEndpoint
|
||||||
connConfig.CfOrg = config.CfOrg
|
connConfig.CfOrg = config.CfOrg
|
||||||
@@ -187,17 +186,17 @@ func initConnection(conn *abapbuild.Connector, config *abapEnvironmentBuildOptio
|
|||||||
connConfig.Parameters.Add("sap-client", config.AbapSourceClient)
|
connConfig.Parameters.Add("sap-client", config.AbapSourceClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := conn.InitBuildFramework(connConfig, *utils, *utils); err != nil {
|
if err := conn.InitBuildFramework(connConfig, utils, utils); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.MaxRuntime = (*utils).getMaxRuntime()
|
conn.MaxRuntime = utils.getMaxRuntime()
|
||||||
conn.PollingInterval = (*utils).getPollingInterval()
|
conn.PollingInterval = utils.getPollingInterval()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***********************************Run Build***************************************************************
|
// ***********************************Run Build***************************************************************
|
||||||
func runBuild(conn *abapbuild.Connector, config *abapEnvironmentBuildOptions, utils *abapEnvironmentBuildUtils, values []abapbuild.Value) ([]abapbuild.Value, error) {
|
func runBuild(conn *abapbuild.Connector, config *abapEnvironmentBuildOptions, utils abapEnvironmentBuildUtils, values []abapbuild.Value) ([]abapbuild.Value, error) {
|
||||||
var finalValues []abapbuild.Value
|
var finalValues []abapbuild.Value
|
||||||
var inputValues abapbuild.Values
|
var inputValues abapbuild.Values
|
||||||
inputValues.Values = values
|
inputValues.Values = values
|
||||||
@@ -272,11 +271,11 @@ func (b *myBuild) Download() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *myBuild) Publish(utils *abapEnvironmentBuildUtils) error {
|
func (b *myBuild) Publish(utils abapEnvironmentBuildUtils) error {
|
||||||
if b.PublishAllDownloadedResultFiles {
|
if b.PublishAllDownloadedResultFiles {
|
||||||
b.PublishAllDownloadedResults("abapEnvironmentBuild", *utils)
|
b.PublishAllDownloadedResults("abapEnvironmentBuild", utils)
|
||||||
} else {
|
} else {
|
||||||
if err := b.PublishDownloadedResults("abapEnvironmentBuild", b.PublishResultFilenames, *utils); err != nil {
|
if err := b.PublishDownloadedResults("abapEnvironmentBuild", b.PublishResultFilenames, utils); err != nil {
|
||||||
return errors.Wrapf(err, "Error during the publish of the result files %s", b.PublishResultFilenames)
|
return errors.Wrapf(err, "Error during the publish of the result files %s", b.PublishResultFilenames)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -330,15 +329,15 @@ func removeAddonDescriptorValues(finalValuesFromBuild []abapbuild.Value, valuesF
|
|||||||
func generateValuesWithAddonDescriptor(config *abapEnvironmentBuildOptions, repoValues []abapbuild.Value) ([]abapbuild.Value, error) {
|
func generateValuesWithAddonDescriptor(config *abapEnvironmentBuildOptions, repoValues []abapbuild.Value) ([]abapbuild.Value, error) {
|
||||||
var values []abapbuild.Value
|
var values []abapbuild.Value
|
||||||
vE := valuesEvaluator{}
|
vE := valuesEvaluator{}
|
||||||
//values from config
|
// values from config
|
||||||
if err := vE.initialize(config.Values); err != nil {
|
if err := vE.initialize(config.Values); err != nil {
|
||||||
return values, err
|
return values, err
|
||||||
}
|
}
|
||||||
//values from addondescriptor
|
// values from addondescriptor
|
||||||
if err := vE.appendValuesIfNotPresent(repoValues, true); err != nil {
|
if err := vE.appendValuesIfNotPresent(repoValues, true); err != nil {
|
||||||
return values, err
|
return values, err
|
||||||
}
|
}
|
||||||
//values from commonepipelineEnvironment
|
// values from commonepipelineEnvironment
|
||||||
if err := vE.appendStringValuesIfNotPresent(config.CpeValues, false); err != nil {
|
if err := vE.appendStringValuesIfNotPresent(config.CpeValues, false); err != nil {
|
||||||
return values, err
|
return values, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import (
|
|||||||
type abapEnvironmentBuildMockUtils struct {
|
type abapEnvironmentBuildMockUtils struct {
|
||||||
*mock.ExecMockRunner
|
*mock.ExecMockRunner
|
||||||
*abapbuild.MockClient
|
*abapbuild.MockClient
|
||||||
|
*mock.FilesMock
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAbapEnvironmentBuildTestsUtils() abapEnvironmentBuildUtils {
|
func newAbapEnvironmentBuildTestsUtils() abapEnvironmentBuildUtils {
|
||||||
@@ -22,6 +23,7 @@ func newAbapEnvironmentBuildTestsUtils() abapEnvironmentBuildUtils {
|
|||||||
utils := abapEnvironmentBuildMockUtils{
|
utils := abapEnvironmentBuildMockUtils{
|
||||||
ExecMockRunner: &mock.ExecMockRunner{},
|
ExecMockRunner: &mock.ExecMockRunner{},
|
||||||
MockClient: &mC,
|
MockClient: &mC,
|
||||||
|
FilesMock: &mock.FilesMock{},
|
||||||
}
|
}
|
||||||
return &utils
|
return &utils
|
||||||
}
|
}
|
||||||
@@ -31,6 +33,7 @@ func newAbapEnvironmentBuildTestsUtilsWithClient() abapEnvironmentBuildUtils {
|
|||||||
utils := abapEnvironmentBuildMockUtils{
|
utils := abapEnvironmentBuildMockUtils{
|
||||||
ExecMockRunner: &mock.ExecMockRunner{},
|
ExecMockRunner: &mock.ExecMockRunner{},
|
||||||
MockClient: &mC,
|
MockClient: &mC,
|
||||||
|
FilesMock: &mock.FilesMock{},
|
||||||
}
|
}
|
||||||
return &utils
|
return &utils
|
||||||
}
|
}
|
||||||
@@ -70,7 +73,7 @@ func TestRunAbapEnvironmentBuild(t *testing.T) {
|
|||||||
config.PublishAllDownloadedResultFiles = true
|
config.PublishAllDownloadedResultFiles = true
|
||||||
utils := newAbapEnvironmentBuildTestsUtils()
|
utils := newAbapEnvironmentBuildTestsUtils()
|
||||||
// test
|
// test
|
||||||
err := runAbapEnvironmentBuild(&config, nil, &utils, &cpe)
|
err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
|
||||||
// assert
|
// assert
|
||||||
finalValues := `[{"value_id":"PHASE","value":"AUNIT"},{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"AunitValue1"},{"value_id":"MyId2","value":"AunitValue2"},{"value_id":"BUILD_FRAMEWORK_MODE","value":"P"}]`
|
finalValues := `[{"value_id":"PHASE","value":"AUNIT"},{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"MyId1","value":"AunitValue1"},{"value_id":"MyId2","value":"AunitValue2"},{"value_id":"BUILD_FRAMEWORK_MODE","value":"P"}]`
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -87,7 +90,7 @@ func TestRunAbapEnvironmentBuild(t *testing.T) {
|
|||||||
config.AbapSourceClient = "001"
|
config.AbapSourceClient = "001"
|
||||||
utils := newAbapEnvironmentBuildTestsUtilsWithClient()
|
utils := newAbapEnvironmentBuildTestsUtilsWithClient()
|
||||||
// test
|
// test
|
||||||
err := runAbapEnvironmentBuild(&config, nil, &utils, &cpe)
|
err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
|
||||||
// assert
|
// assert
|
||||||
finalValues := `[{"value_id":"PHASE","value":"AUNIT"},{"value_id":"SUN","value":"SUMMER"}]`
|
finalValues := `[{"value_id":"PHASE","value":"AUNIT"},{"value_id":"SUN","value":"SUMMER"}]`
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
@@ -105,7 +108,7 @@ func TestRunAbapEnvironmentBuild(t *testing.T) {
|
|||||||
config.PublishResultFilenames = []string{"SAR_XML"}
|
config.PublishResultFilenames = []string{"SAR_XML"}
|
||||||
utils := newAbapEnvironmentBuildTestsUtils()
|
utils := newAbapEnvironmentBuildTestsUtils()
|
||||||
// test
|
// test
|
||||||
err := runAbapEnvironmentBuild(&config, nil, &utils, &cpe)
|
err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
|
||||||
// assert
|
// assert
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
})
|
})
|
||||||
@@ -124,7 +127,7 @@ func TestRunAbapEnvironmentBuild(t *testing.T) {
|
|||||||
config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"MyId1"},{"use":"Status","renameTo":"MyId2"}]`
|
config.UseFieldsOfAddonDescriptor = `[{"use":"Name","renameTo":"MyId1"},{"use":"Status","renameTo":"MyId2"}]`
|
||||||
utils := newAbapEnvironmentBuildTestsUtils()
|
utils := newAbapEnvironmentBuildTestsUtils()
|
||||||
// test
|
// test
|
||||||
err := runAbapEnvironmentBuild(&config, nil, &utils, &cpe)
|
err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
|
||||||
// assert
|
// assert
|
||||||
finalValues := `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"BUILD_FRAMEWORK_MODE","value":"P"}]`
|
finalValues := `[{"value_id":"PACKAGES","value":"/BUILD/AUNIT_DUMMY_TESTS"},{"value_id":"BUILD_FRAMEWORK_MODE","value":"P"}]`
|
||||||
err = json.Unmarshal([]byte(finalValues), &expectedValueList)
|
err = json.Unmarshal([]byte(finalValues), &expectedValueList)
|
||||||
@@ -146,7 +149,7 @@ func TestRunAbapEnvironmentBuild(t *testing.T) {
|
|||||||
config.PublishResultFilenames = []string{"SAR_XML"}
|
config.PublishResultFilenames = []string{"SAR_XML"}
|
||||||
utils := newAbapEnvironmentBuildTestsUtils()
|
utils := newAbapEnvironmentBuildTestsUtils()
|
||||||
// test
|
// test
|
||||||
err := runAbapEnvironmentBuild(&config, nil, &utils, &cpe)
|
err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
|
||||||
// assert
|
// assert
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
})
|
})
|
||||||
@@ -162,7 +165,7 @@ func TestRunAbapEnvironmentBuild(t *testing.T) {
|
|||||||
config.PublishAllDownloadedResultFiles = true
|
config.PublishAllDownloadedResultFiles = true
|
||||||
utils := newAbapEnvironmentBuildTestsUtils()
|
utils := newAbapEnvironmentBuildTestsUtils()
|
||||||
// test
|
// test
|
||||||
err := runAbapEnvironmentBuild(&config, nil, &utils, &cpe)
|
err := runAbapEnvironmentBuild(&config, nil, utils, &cpe)
|
||||||
// assert
|
// assert
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"io/ioutil"
|
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/abaputils"
|
"github.com/SAP/jenkins-library/pkg/abaputils"
|
||||||
@@ -53,7 +53,6 @@ func TestFetchXcsrfTokenFromHead(t *testing.T) {
|
|||||||
func TestCheckATCSystemConfigurationFile(t *testing.T) {
|
func TestCheckATCSystemConfigurationFile(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
t.Run("Check ATC Configuration File - empty", func(t *testing.T) {
|
t.Run("Check ATC Configuration File - empty", func(t *testing.T) {
|
||||||
|
|
||||||
errExpected := "pushing ATC System Configuration failed. Reason: Configured Filelocation is empty (File: atcSystemConfig.json)"
|
errExpected := "pushing ATC System Configuration failed. Reason: Configured Filelocation is empty (File: atcSystemConfig.json)"
|
||||||
var parsedConfigurationJsonExpected parsedConfigJsonWithExpand
|
var parsedConfigurationJsonExpected parsedConfigJsonWithExpand
|
||||||
var atcSystemConfiguartionJsonFileExpected []byte
|
var atcSystemConfiguartionJsonFileExpected []byte
|
||||||
@@ -71,7 +70,6 @@ func TestHandleHttpResponse(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("failiure case: HandleHttpResponse", func(t *testing.T) {
|
t.Run("failiure case: HandleHttpResponse", func(t *testing.T) {
|
||||||
|
|
||||||
bodyText := `
|
bodyText := `
|
||||||
--B772E21DAA42B9571C778276B829D6C20
|
--B772E21DAA42B9571C778276B829D6C20
|
||||||
Content-Type: multipart/mixed; boundary=B772E21DAA42B9571C778276B829D6C21
|
Content-Type: multipart/mixed; boundary=B772E21DAA42B9571C778276B829D6C21
|
||||||
@@ -139,13 +137,12 @@ cache-control: no-cache, no-store, must-revalidate
|
|||||||
}
|
}
|
||||||
resp.Header.Set("Content-type", "multipart/mixed")
|
resp.Header.Set("Content-type", "multipart/mixed")
|
||||||
err = HandleHttpResponse(resp, err, "Unit Test", con)
|
err = HandleHttpResponse(resp, err, "Unit Test", con)
|
||||||
//inner error expected
|
// inner error expected
|
||||||
errExpected := "Outer Response Code: 200 - but at least one Inner response returned StatusCode 4* or 5*. Please check Log for details."
|
errExpected := "Outer Response Code: 200 - but at least one Inner response returned StatusCode 4* or 5*. Please check Log for details."
|
||||||
assert.Equal(t, errExpected, err.Error())
|
assert.Equal(t, errExpected, err.Error())
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("success case: HandleHttpResponse", func(t *testing.T) {
|
t.Run("success case: HandleHttpResponse", func(t *testing.T) {
|
||||||
|
|
||||||
bodyText := `
|
bodyText := `
|
||||||
--B772E21DAA42B9571C778276B829D6C20
|
--B772E21DAA42B9571C778276B829D6C20
|
||||||
Content-Type: multipart/mixed; boundary=B772E21DAA42B9571C778276B829D6C21
|
Content-Type: multipart/mixed; boundary=B772E21DAA42B9571C778276B829D6C21
|
||||||
@@ -221,7 +218,6 @@ func TestBuildATCSystemConfigBatchRequest(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("success case: BuildATCSystemConfigBatch - Config Base & 1 Priority", func(t *testing.T) {
|
t.Run("success case: BuildATCSystemConfigBatch - Config Base & 1 Priority", func(t *testing.T) {
|
||||||
|
|
||||||
batchATCSystemConfigFileExpected := `
|
batchATCSystemConfigFileExpected := `
|
||||||
--request-separator
|
--request-separator
|
||||||
Content-Type: multipart/mixed;boundary=changeset
|
Content-Type: multipart/mixed;boundary=changeset
|
||||||
@@ -250,7 +246,7 @@ Content-Type: application/json
|
|||||||
|
|
||||||
--request-separator--`
|
--request-separator--`
|
||||||
|
|
||||||
//no Configuration name supplied
|
// no Configuration name supplied
|
||||||
atcSystemConfigFileString := `{
|
atcSystemConfigFileString := `{
|
||||||
"conf_name": "UNITTEST_PIPERSTEP",
|
"conf_name": "UNITTEST_PIPERSTEP",
|
||||||
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
||||||
@@ -280,11 +276,9 @@ Content-Type: application/json
|
|||||||
t.Fatal("Failed to Build ATC System Config Batch")
|
t.Fatal("Failed to Build ATC System Config Batch")
|
||||||
}
|
}
|
||||||
assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("success case: BuildATCSystemConfigBatch - Config Base & 2 Priorities", func(t *testing.T) {
|
t.Run("success case: BuildATCSystemConfigBatch - Config Base & 2 Priorities", func(t *testing.T) {
|
||||||
|
|
||||||
batchATCSystemConfigFileExpected := `
|
batchATCSystemConfigFileExpected := `
|
||||||
--request-separator
|
--request-separator
|
||||||
Content-Type: multipart/mixed;boundary=changeset
|
Content-Type: multipart/mixed;boundary=changeset
|
||||||
@@ -323,7 +317,7 @@ Content-Type: application/json
|
|||||||
|
|
||||||
--request-separator--`
|
--request-separator--`
|
||||||
|
|
||||||
//no Configuration name supplied
|
// no Configuration name supplied
|
||||||
atcSystemConfigFileString := `{
|
atcSystemConfigFileString := `{
|
||||||
"conf_name": "UNITTEST_PIPERSTEP",
|
"conf_name": "UNITTEST_PIPERSTEP",
|
||||||
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
||||||
@@ -358,11 +352,9 @@ Content-Type: application/json
|
|||||||
t.Fatal("Failed to Build ATC System Config Batch Request")
|
t.Fatal("Failed to Build ATC System Config Batch Request")
|
||||||
}
|
}
|
||||||
assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("success case: BuildATCSystemConfigBatch - Config Base only (no existing _priorities)", func(t *testing.T) {
|
t.Run("success case: BuildATCSystemConfigBatch - Config Base only (no existing _priorities)", func(t *testing.T) {
|
||||||
|
|
||||||
batchATCSystemConfigFileExpected := `
|
batchATCSystemConfigFileExpected := `
|
||||||
--request-separator
|
--request-separator
|
||||||
Content-Type: multipart/mixed;boundary=changeset
|
Content-Type: multipart/mixed;boundary=changeset
|
||||||
@@ -381,7 +373,7 @@ Content-Type: application/json
|
|||||||
|
|
||||||
--request-separator--`
|
--request-separator--`
|
||||||
|
|
||||||
//no Configuration name supplied
|
// no Configuration name supplied
|
||||||
atcSystemConfigFileString := `{
|
atcSystemConfigFileString := `{
|
||||||
"conf_name": "UNITTEST_PIPERSTEP",
|
"conf_name": "UNITTEST_PIPERSTEP",
|
||||||
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
||||||
@@ -403,11 +395,9 @@ Content-Type: application/json
|
|||||||
t.Fatal("Failed to Build ATC System Config Batch")
|
t.Fatal("Failed to Build ATC System Config Batch")
|
||||||
}
|
}
|
||||||
assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("success case: BuildATCSystemConfigBatch - Config Base only (empty expand _priorities)", func(t *testing.T) {
|
t.Run("success case: BuildATCSystemConfigBatch - Config Base only (empty expand _priorities)", func(t *testing.T) {
|
||||||
|
|
||||||
batchATCSystemConfigFileExpected := `
|
batchATCSystemConfigFileExpected := `
|
||||||
--request-separator
|
--request-separator
|
||||||
Content-Type: multipart/mixed;boundary=changeset
|
Content-Type: multipart/mixed;boundary=changeset
|
||||||
@@ -426,7 +416,7 @@ Content-Type: application/json
|
|||||||
|
|
||||||
--request-separator--`
|
--request-separator--`
|
||||||
|
|
||||||
//no Configuration name supplied
|
// no Configuration name supplied
|
||||||
atcSystemConfigFileString := `{
|
atcSystemConfigFileString := `{
|
||||||
"conf_name": "UNITTEST_PIPERSTEP",
|
"conf_name": "UNITTEST_PIPERSTEP",
|
||||||
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
||||||
@@ -450,14 +440,12 @@ Content-Type: application/json
|
|||||||
t.Fatal("Failed to Build ATC System Config Batch")
|
t.Fatal("Failed to Build ATC System Config Batch")
|
||||||
}
|
}
|
||||||
assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("failure case: BuildATCSystemConfigBatch", func(t *testing.T) {
|
t.Run("failure case: BuildATCSystemConfigBatch", func(t *testing.T) {
|
||||||
|
|
||||||
batchATCSystemConfigFileExpected := ``
|
batchATCSystemConfigFileExpected := ``
|
||||||
|
|
||||||
//no Configuration name supplied
|
// no Configuration name supplied
|
||||||
atcSystemConfigFileString := `{
|
atcSystemConfigFileString := `{
|
||||||
"conf_name": "UNITTEST_PIPERSTEP",
|
"conf_name": "UNITTEST_PIPERSTEP",
|
||||||
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
||||||
@@ -487,14 +475,14 @@ Content-Type: application/json
|
|||||||
t.Fatal("Failed to Build ATC System Config Batch")
|
t.Fatal("Failed to Build ATC System Config Batch")
|
||||||
}
|
}
|
||||||
assert.NotEqual(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
assert.NotEqual(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile)
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
t.Run("run Step Failure - ATC System Configuration File empty", func(t *testing.T) {
|
t.Run("run Step Failure - ATC System Configuration File empty", func(t *testing.T) {
|
||||||
var autils = abaputils.AUtilsMock{}
|
autils := abaputils.AUtilsMock{}
|
||||||
defer autils.Cleanup()
|
defer autils.Cleanup()
|
||||||
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
||||||
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
||||||
@@ -511,19 +499,12 @@ func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
oldCWD, _ := os.Getwd()
|
|
||||||
_ = os.Chdir(dir)
|
|
||||||
// clean up tmp dir
|
|
||||||
|
|
||||||
defer func() {
|
config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: filepath.Join(dir, "atcSystemConfig.json")}
|
||||||
_ = os.Chdir(oldCWD)
|
|
||||||
}()
|
|
||||||
|
|
||||||
config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: "atcSystemConfig.json"}
|
|
||||||
|
|
||||||
atcSystemConfigFileString := ``
|
atcSystemConfigFileString := ``
|
||||||
|
|
||||||
err := ioutil.WriteFile(config.AtcSystemConfigFilePath, []byte(atcSystemConfigFileString), 0644)
|
err := os.WriteFile(config.AtcSystemConfigFilePath, []byte(atcSystemConfigFileString), 0o644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Failed to write File: " + config.AtcSystemConfigFilePath)
|
t.Fatal("Failed to write File: " + config.AtcSystemConfigFilePath)
|
||||||
}
|
}
|
||||||
@@ -535,7 +516,7 @@ func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("run Step Failure - ATC System Configuration invalid", func(t *testing.T) {
|
t.Run("run Step Failure - ATC System Configuration invalid", func(t *testing.T) {
|
||||||
var autils = abaputils.AUtilsMock{}
|
autils := abaputils.AUtilsMock{}
|
||||||
defer autils.Cleanup()
|
defer autils.Cleanup()
|
||||||
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
||||||
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
||||||
@@ -552,17 +533,10 @@ func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
oldCWD, _ := os.Getwd()
|
|
||||||
_ = os.Chdir(dir)
|
|
||||||
// clean up tmp dir
|
|
||||||
|
|
||||||
defer func() {
|
config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: filepath.Join(dir, "atcSystemConfig.json")}
|
||||||
_ = os.Chdir(oldCWD)
|
|
||||||
}()
|
|
||||||
|
|
||||||
config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: "atcSystemConfig.json"}
|
// no Configuration name supplied
|
||||||
|
|
||||||
//no Configuration name supplied
|
|
||||||
atcSystemConfigFileString := `{
|
atcSystemConfigFileString := `{
|
||||||
"conf_name": "",
|
"conf_name": "",
|
||||||
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
||||||
@@ -585,7 +559,7 @@ func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
err := ioutil.WriteFile(config.AtcSystemConfigFilePath, []byte(atcSystemConfigFileString), 0644)
|
err := os.WriteFile(config.AtcSystemConfigFilePath, []byte(atcSystemConfigFileString), 0o644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Failed to write File: " + config.AtcSystemConfigFilePath)
|
t.Fatal("Failed to write File: " + config.AtcSystemConfigFilePath)
|
||||||
}
|
}
|
||||||
@@ -597,7 +571,7 @@ func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("run Step Successful - Push ATC System Configuration", func(t *testing.T) {
|
t.Run("run Step Successful - Push ATC System Configuration", func(t *testing.T) {
|
||||||
var autils = abaputils.AUtilsMock{}
|
autils := abaputils.AUtilsMock{}
|
||||||
defer autils.Cleanup()
|
defer autils.Cleanup()
|
||||||
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
||||||
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
||||||
@@ -614,17 +588,10 @@ func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dir := t.TempDir()
|
dir := t.TempDir()
|
||||||
oldCWD, _ := os.Getwd()
|
|
||||||
_ = os.Chdir(dir)
|
|
||||||
// clean up tmp dir
|
|
||||||
|
|
||||||
defer func() {
|
config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: filepath.Join(dir, "atcSystemConfig.json")}
|
||||||
_ = os.Chdir(oldCWD)
|
|
||||||
}()
|
|
||||||
|
|
||||||
config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: "atcSystemConfig.json"}
|
// valid ATC System Configuration File
|
||||||
|
|
||||||
//valid ATC System Configuration File
|
|
||||||
atcSystemConfigFileString := `{
|
atcSystemConfigFileString := `{
|
||||||
"conf_name": "UNITTEST_PIPERSTEP",
|
"conf_name": "UNITTEST_PIPERSTEP",
|
||||||
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT",
|
||||||
@@ -647,7 +614,7 @@ func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
err := ioutil.WriteFile(config.AtcSystemConfigFilePath, []byte(atcSystemConfigFileString), 0644)
|
err := os.WriteFile(config.AtcSystemConfigFilePath, []byte(atcSystemConfigFileString), 0o644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal("Failed to write File: " + config.AtcSystemConfigFilePath)
|
t.Fatal("Failed to write File: " + config.AtcSystemConfigFilePath)
|
||||||
}
|
}
|
||||||
@@ -657,7 +624,7 @@ func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("run Step Failure - ATC System Configuration File does not exist", func(t *testing.T) {
|
t.Run("run Step Failure - ATC System Configuration File does not exist", func(t *testing.T) {
|
||||||
var autils = abaputils.AUtilsMock{}
|
autils := abaputils.AUtilsMock{}
|
||||||
defer autils.Cleanup()
|
defer autils.Cleanup()
|
||||||
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
||||||
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ func abapEnvironmentRunATCCheck(options abapEnvironmentRunATCCheckOptions, telem
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
client := piperhttp.Client{}
|
client := piperhttp.Client{}
|
||||||
|
fileUtils := piperutils.Files{}
|
||||||
cookieJar, _ := cookiejar.New(nil)
|
cookieJar, _ := cookiejar.New(nil)
|
||||||
clientOptions := piperhttp.ClientOptions{
|
clientOptions := piperhttp.ClientOptions{
|
||||||
CookieJar: cookieJar,
|
CookieJar: cookieJar,
|
||||||
@@ -62,7 +63,7 @@ func abapEnvironmentRunATCCheck(options abapEnvironmentRunATCCheckOptions, telem
|
|||||||
resp, err = triggerATCRun(options, details, &client)
|
resp, err = triggerATCRun(options, details, &client)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = fetchAndPersistATCResults(resp, details, &client, options.AtcResultsFileName, options.GenerateHTML)
|
err = fetchAndPersistATCResults(resp, details, &client, &fileUtils, options.AtcResultsFileName, options.GenerateHTML)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Entry().WithError(err).Fatal("step execution failed")
|
log.Entry().WithError(err).Fatal("step execution failed")
|
||||||
@@ -71,7 +72,7 @@ func abapEnvironmentRunATCCheck(options abapEnvironmentRunATCCheckOptions, telem
|
|||||||
log.Entry().Info("ATC run completed successfully. If there are any results from the respective run they will be listed in the logs above as well as being saved in the output .xml file")
|
log.Entry().Info("ATC run completed successfully. If there are any results from the respective run they will be listed in the logs above as well as being saved in the output .xml file")
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchAndPersistATCResults(resp *http.Response, details abaputils.ConnectionDetailsHTTP, client piperhttp.Sender, atcResultFileName string, generateHTML bool) error {
|
func fetchAndPersistATCResults(resp *http.Response, details abaputils.ConnectionDetailsHTTP, client piperhttp.Sender, utils piperutils.FileUtils, atcResultFileName string, generateHTML bool) error {
|
||||||
var err error
|
var err error
|
||||||
abapEndpoint := details.URL
|
abapEndpoint := details.URL
|
||||||
location := resp.Header.Get("Location")
|
location := resp.Header.Get("Location")
|
||||||
@@ -88,7 +89,7 @@ func fetchAndPersistATCResults(resp *http.Response, details abaputils.Connection
|
|||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
err = logAndPersistATCResult(body, atcResultFileName, generateHTML)
|
err = logAndPersistATCResult(utils, body, atcResultFileName, generateHTML)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Handling ATC result failed: %w", err)
|
return fmt.Errorf("Handling ATC result failed: %w", err)
|
||||||
@@ -202,7 +203,7 @@ func getATCObjectSet(ATCConfig ATCConfiguration) (objectSet string, err error) {
|
|||||||
return objectSet, nil
|
return objectSet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func logAndPersistATCResult(body []byte, atcResultFileName string, generateHTML bool) error {
|
func logAndPersistATCResult(utils piperutils.FileUtils, body []byte, atcResultFileName string, generateHTML bool) error {
|
||||||
if len(body) == 0 {
|
if len(body) == 0 {
|
||||||
return fmt.Errorf("Parsing ATC result failed: %w", errors.New("Body is empty, can't parse empty body"))
|
return fmt.Errorf("Parsing ATC result failed: %w", errors.New("Body is empty, can't parse empty body"))
|
||||||
}
|
}
|
||||||
@@ -241,7 +242,7 @@ func logAndPersistATCResult(body []byte, atcResultFileName string, generateHTML
|
|||||||
reports = append(reports, piperutils.Path{Target: atcResultFileName, Name: "ATC Results HTML file", Mandatory: true})
|
reports = append(reports, piperutils.Path{Target: atcResultFileName, Name: "ATC Results HTML file", Mandatory: true})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
piperutils.PersistReportsAndLinks("abapEnvironmentRunATCCheck", "", reports, nil)
|
piperutils.PersistReportsAndLinks("abapEnvironmentRunATCCheck", "", utils, reports, nil)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Writing results failed: %w", err)
|
return fmt.Errorf("Writing results failed: %w", err)
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ func TestHostConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
execRunner := &mock.ExecMockRunner{}
|
execRunner := &mock.ExecMockRunner{}
|
||||||
var autils = abaputils.AbapUtils{
|
autils := abaputils.AbapUtils{
|
||||||
Exec: execRunner,
|
Exec: execRunner,
|
||||||
}
|
}
|
||||||
var con abaputils.ConnectionDetailsHTTP
|
var con abaputils.ConnectionDetailsHTTP
|
||||||
@@ -37,7 +37,7 @@ func TestHostConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
t.Run("No host/ServiceKey configuration", func(t *testing.T) {
|
t.Run("No host/ServiceKey configuration", func(t *testing.T) {
|
||||||
//Testing without CfOrg parameter
|
// Testing without CfOrg parameter
|
||||||
config := abaputils.AbapEnvironmentOptions{
|
config := abaputils.AbapEnvironmentOptions{
|
||||||
CfAPIEndpoint: "https://api.endpoint.com",
|
CfAPIEndpoint: "https://api.endpoint.com",
|
||||||
CfSpace: "testSpace",
|
CfSpace: "testSpace",
|
||||||
@@ -51,7 +51,7 @@ func TestHostConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
execRunner := &mock.ExecMockRunner{}
|
execRunner := &mock.ExecMockRunner{}
|
||||||
var autils = abaputils.AbapUtils{
|
autils := abaputils.AbapUtils{
|
||||||
Exec: execRunner,
|
Exec: execRunner,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ func TestHostConfig(t *testing.T) {
|
|||||||
AbapEnvOptions: config,
|
AbapEnvOptions: config,
|
||||||
}
|
}
|
||||||
execRunner := &mock.ExecMockRunner{}
|
execRunner := &mock.ExecMockRunner{}
|
||||||
var autils = abaputils.AbapUtils{
|
autils := abaputils.AbapUtils{
|
||||||
Exec: execRunner,
|
Exec: execRunner,
|
||||||
}
|
}
|
||||||
var con abaputils.ConnectionDetailsHTTP
|
var con abaputils.ConnectionDetailsHTTP
|
||||||
@@ -242,7 +242,7 @@ func TestParseATCResult(t *testing.T) {
|
|||||||
</file>
|
</file>
|
||||||
</checkstyle>`
|
</checkstyle>`
|
||||||
body := []byte(bodyString)
|
body := []byte(bodyString)
|
||||||
err := logAndPersistATCResult(body, "ATCResults.xml", false)
|
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false)
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
})
|
})
|
||||||
t.Run("succes case: test parsing empty XML result", func(t *testing.T) {
|
t.Run("succes case: test parsing empty XML result", func(t *testing.T) {
|
||||||
@@ -257,14 +257,14 @@ func TestParseATCResult(t *testing.T) {
|
|||||||
<checkstyle>
|
<checkstyle>
|
||||||
</checkstyle>`
|
</checkstyle>`
|
||||||
body := []byte(bodyString)
|
body := []byte(bodyString)
|
||||||
err := logAndPersistATCResult(body, "ATCResults.xml", false)
|
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false)
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
})
|
})
|
||||||
t.Run("failure case: parsing empty xml", func(t *testing.T) {
|
t.Run("failure case: parsing empty xml", func(t *testing.T) {
|
||||||
var bodyString string
|
var bodyString string
|
||||||
body := []byte(bodyString)
|
body := []byte(bodyString)
|
||||||
|
|
||||||
err := logAndPersistATCResult(body, "ATCResults.xml", false)
|
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false)
|
||||||
assert.EqualError(t, err, "Parsing ATC result failed: Body is empty, can't parse empty body")
|
assert.EqualError(t, err, "Parsing ATC result failed: Body is empty, can't parse empty body")
|
||||||
})
|
})
|
||||||
t.Run("failure case: html response", func(t *testing.T) {
|
t.Run("failure case: html response", func(t *testing.T) {
|
||||||
@@ -277,7 +277,7 @@ func TestParseATCResult(t *testing.T) {
|
|||||||
}()
|
}()
|
||||||
bodyString := `<html><head><title>HTMLTestResponse</title</head></html>`
|
bodyString := `<html><head><title>HTMLTestResponse</title</head></html>`
|
||||||
body := []byte(bodyString)
|
body := []byte(bodyString)
|
||||||
err := logAndPersistATCResult(body, "ATCResults.xml", false)
|
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false)
|
||||||
assert.EqualError(t, err, "The Software Component could not be checked. Please make sure the respective Software Component has been cloned successfully on the system")
|
assert.EqualError(t, err, "The Software Component could not be checked. Please make sure the respective Software Component has been cloned successfully on the system")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -294,7 +294,6 @@ func TestBuildATCCheckBody(t *testing.T) {
|
|||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
})
|
})
|
||||||
t.Run("success case: Test build body with example yaml config", func(t *testing.T) {
|
t.Run("success case: Test build body with example yaml config", func(t *testing.T) {
|
||||||
|
|
||||||
expectedObjectSet := "<obj:objectSet><obj:softwarecomponents><obj:softwarecomponent value=\"testSoftwareComponent\"/><obj:softwarecomponent value=\"testSoftwareComponent2\"/></obj:softwarecomponents><obj:packages><obj:package value=\"testPackage\" includeSubpackages=\"true\"/><obj:package value=\"testPackage2\" includeSubpackages=\"false\"/></obj:packages></obj:objectSet>"
|
expectedObjectSet := "<obj:objectSet><obj:softwarecomponents><obj:softwarecomponent value=\"testSoftwareComponent\"/><obj:softwarecomponent value=\"testSoftwareComponent2\"/></obj:softwarecomponents><obj:packages><obj:package value=\"testPackage\" includeSubpackages=\"true\"/><obj:package value=\"testPackage2\" includeSubpackages=\"false\"/></obj:packages></obj:objectSet>"
|
||||||
|
|
||||||
config := ATCConfiguration{
|
config := ATCConfiguration{
|
||||||
@@ -319,7 +318,6 @@ func TestBuildATCCheckBody(t *testing.T) {
|
|||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
})
|
})
|
||||||
t.Run("failure case: Test build body with example yaml config with only packages and no software components", func(t *testing.T) {
|
t.Run("failure case: Test build body with example yaml config with only packages and no software components", func(t *testing.T) {
|
||||||
|
|
||||||
expectedObjectSet := `<obj:objectSet><obj:packages><obj:package value="testPackage" includeSubpackages="true"/><obj:package value="testPackage2" includeSubpackages="false"/></obj:packages></obj:objectSet>`
|
expectedObjectSet := `<obj:objectSet><obj:packages><obj:package value="testPackage" includeSubpackages="true"/><obj:package value="testPackage2" includeSubpackages="false"/></obj:packages></obj:objectSet>`
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
@@ -342,7 +340,6 @@ func TestBuildATCCheckBody(t *testing.T) {
|
|||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
})
|
})
|
||||||
t.Run("success case: Test build body with example yaml config with no packages and only software components", func(t *testing.T) {
|
t.Run("success case: Test build body with example yaml config with no packages and only software components", func(t *testing.T) {
|
||||||
|
|
||||||
expectedObjectSet := `<obj:objectSet><obj:softwarecomponents><obj:softwarecomponent value="testSoftwareComponent"/><obj:softwarecomponent value="testSoftwareComponent2"/></obj:softwarecomponents></obj:objectSet>`
|
expectedObjectSet := `<obj:objectSet><obj:softwarecomponents><obj:softwarecomponent value="testSoftwareComponent"/><obj:softwarecomponent value="testSoftwareComponent2"/></obj:softwarecomponents></obj:objectSet>`
|
||||||
|
|
||||||
config := ATCConfiguration{
|
config := ATCConfiguration{
|
||||||
@@ -365,7 +362,7 @@ func TestBuildATCCheckBody(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestGenerateHTMLDocument(t *testing.T) {
|
func TestGenerateHTMLDocument(t *testing.T) {
|
||||||
//Failure case is not needed --> all failing cases would be depended on parsedXML *Result which is covered in TestParseATCResult
|
// Failure case is not needed --> all failing cases would be depended on parsedXML *Result which is covered in TestParseATCResult
|
||||||
t.Run("success case: html response", func(t *testing.T) {
|
t.Run("success case: html response", func(t *testing.T) {
|
||||||
expectedResult := "<!DOCTYPE html><html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>ATC Results</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><style>table,th,td {border: 1px solid black;border-collapse:collapse;}th,td{padding: 5px;text-align:left;font-size:medium;}</style></head><body><h1 style=\"text-align:left;font-size:large\">ATC Results</h1><table style=\"width:100%\"><tr><th>Severity</th><th>File</th><th>Message</th><th>Line</th><th>Checked by</th></tr><tr style=\"background-color: rgba(227,85,0)\"><td>error</td><td>testFile2</td><td>testMessage</td><td style=\"text-align:center\">1</td><td>sourceTester</td></tr><tr style=\"background-color: rgba(255,175,0, 0.75)\"><td>warning</td><td>testFile</td><td>testMessage2</td><td style=\"text-align:center\">2</td><td>sourceTester</td></tr><tr style=\"background-color: rgba(255,175,0, 0.2)\"><td>info</td><td>testFile</td><td>testMessage1</td><td style=\"text-align:center\">1</td><td>sourceTester</td></tr></table></body></html>"
|
expectedResult := "<!DOCTYPE html><html lang=\"en\" xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>ATC Results</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><style>table,th,td {border: 1px solid black;border-collapse:collapse;}th,td{padding: 5px;text-align:left;font-size:medium;}</style></head><body><h1 style=\"text-align:left;font-size:large\">ATC Results</h1><table style=\"width:100%\"><tr><th>Severity</th><th>File</th><th>Message</th><th>Line</th><th>Checked by</th></tr><tr style=\"background-color: rgba(227,85,0)\"><td>error</td><td>testFile2</td><td>testMessage</td><td style=\"text-align:center\">1</td><td>sourceTester</td></tr><tr style=\"background-color: rgba(255,175,0, 0.75)\"><td>warning</td><td>testFile</td><td>testMessage2</td><td style=\"text-align:center\">2</td><td>sourceTester</td></tr><tr style=\"background-color: rgba(255,175,0, 0.2)\"><td>info</td><td>testFile</td><td>testMessage1</td><td style=\"text-align:center\">1</td><td>sourceTester</td></tr></table></body></html>"
|
||||||
|
|
||||||
@@ -393,9 +390,7 @@ func TestGenerateHTMLDocument(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestResolveConfiguration(t *testing.T) {
|
func TestResolveConfiguration(t *testing.T) {
|
||||||
|
|
||||||
t.Run("resolve atcConfig-yml with ATC Set", func(t *testing.T) {
|
t.Run("resolve atcConfig-yml with ATC Set", func(t *testing.T) {
|
||||||
|
|
||||||
expectedBodyString := "<?xml version=\"1.0\" encoding=\"UTF-8\"?><atc:runparameters xmlns:atc=\"http://www.sap.com/adt/atc\" xmlns:obj=\"http://www.sap.com/adt/objectset\" checkVariant=\"MY_TEST\" configuration=\"MY_CONFIG\"><obj:objectSet><obj:softwarecomponents><obj:softwarecomponent value=\"Z_TEST\"/><obj:softwarecomponent value=\"/DMO/SWC\"/></obj:softwarecomponents><obj:packages><obj:package value=\"Z_TEST\" includeSubpackages=\"false\"/><obj:package value=\"Z_TEST_TREE\" includeSubpackages=\"true\"/></obj:packages></obj:objectSet></atc:runparameters>"
|
expectedBodyString := "<?xml version=\"1.0\" encoding=\"UTF-8\"?><atc:runparameters xmlns:atc=\"http://www.sap.com/adt/atc\" xmlns:obj=\"http://www.sap.com/adt/objectset\" checkVariant=\"MY_TEST\" configuration=\"MY_CONFIG\"><obj:objectSet><obj:softwarecomponents><obj:softwarecomponent value=\"Z_TEST\"/><obj:softwarecomponent value=\"/DMO/SWC\"/></obj:softwarecomponents><obj:packages><obj:package value=\"Z_TEST\" includeSubpackages=\"false\"/><obj:package value=\"Z_TEST_TREE\" includeSubpackages=\"true\"/></obj:packages></obj:objectSet></atc:runparameters>"
|
||||||
config := abapEnvironmentRunATCCheckOptions{
|
config := abapEnvironmentRunATCCheckOptions{
|
||||||
AtcConfig: "atc.yml",
|
AtcConfig: "atc.yml",
|
||||||
@@ -421,17 +416,15 @@ atcobjects:
|
|||||||
- name: /DMO/SWC
|
- name: /DMO/SWC
|
||||||
`
|
`
|
||||||
|
|
||||||
err := ioutil.WriteFile(config.AtcConfig, []byte(yamlBody), 0644)
|
err := ioutil.WriteFile(config.AtcConfig, []byte(yamlBody), 0o644)
|
||||||
if assert.Equal(t, err, nil) {
|
if assert.Equal(t, err, nil) {
|
||||||
bodyString, err := buildATCRequestBody(config)
|
bodyString, err := buildATCRequestBody(config)
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
assert.Equal(t, expectedBodyString, bodyString)
|
assert.Equal(t, expectedBodyString, bodyString)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("resolve atcConfig-yml with OSL", func(t *testing.T) {
|
t.Run("resolve atcConfig-yml with OSL", func(t *testing.T) {
|
||||||
|
|
||||||
config := abapEnvironmentRunATCCheckOptions{
|
config := abapEnvironmentRunATCCheckOptions{
|
||||||
AtcConfig: "atc.yml",
|
AtcConfig: "atc.yml",
|
||||||
}
|
}
|
||||||
@@ -459,7 +452,7 @@ objectset:
|
|||||||
`
|
`
|
||||||
expectedBodyString := "<?xml version=\"1.0\" encoding=\"UTF-8\"?><atc:runparameters xmlns:atc=\"http://www.sap.com/adt/atc\" xmlns:obj=\"http://www.sap.com/adt/objectset\" checkVariant=\"MY_TEST\" configuration=\"MY_CONFIG\"><osl:objectSet xsi:type=\"multiPropertySet\" xmlns:osl=\"http://www.sap.com/api/osl\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><osl:package name=\"Z_TEST\"/><osl:package name=\"Z_TEST_TREE\" includeSubpackages=\"true\"/><osl:softwareComponent name=\"Z_TEST\"/><osl:softwareComponent name=\"/DMO/SWC\"/></osl:objectSet></atc:runparameters>"
|
expectedBodyString := "<?xml version=\"1.0\" encoding=\"UTF-8\"?><atc:runparameters xmlns:atc=\"http://www.sap.com/adt/atc\" xmlns:obj=\"http://www.sap.com/adt/objectset\" checkVariant=\"MY_TEST\" configuration=\"MY_CONFIG\"><osl:objectSet xsi:type=\"multiPropertySet\" xmlns:osl=\"http://www.sap.com/api/osl\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><osl:package name=\"Z_TEST\"/><osl:package name=\"Z_TEST_TREE\" includeSubpackages=\"true\"/><osl:softwareComponent name=\"Z_TEST\"/><osl:softwareComponent name=\"/DMO/SWC\"/></osl:objectSet></atc:runparameters>"
|
||||||
|
|
||||||
err := ioutil.WriteFile(config.AtcConfig, []byte(yamlBody), 0644)
|
err := ioutil.WriteFile(config.AtcConfig, []byte(yamlBody), 0o644)
|
||||||
if assert.Equal(t, err, nil) {
|
if assert.Equal(t, err, nil) {
|
||||||
bodyString, err := buildATCRequestBody(config)
|
bodyString, err := buildATCRequestBody(config)
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
@@ -468,7 +461,6 @@ objectset:
|
|||||||
})
|
})
|
||||||
|
|
||||||
t.Run("resolve repo-yml", func(t *testing.T) {
|
t.Run("resolve repo-yml", func(t *testing.T) {
|
||||||
|
|
||||||
expectedBodyString := "<?xml version=\"1.0\" encoding=\"UTF-8\"?><atc:runparameters xmlns:atc=\"http://www.sap.com/adt/atc\" xmlns:obj=\"http://www.sap.com/adt/objectset\" checkVariant=\"ABAP_CLOUD_DEVELOPMENT_DEFAULT\"><obj:objectSet><obj:softwarecomponents><obj:softwarecomponent value=\"Z_TEST\"/><obj:softwarecomponent value=\"/DMO/SWC\"/></obj:softwarecomponents></obj:objectSet></atc:runparameters>"
|
expectedBodyString := "<?xml version=\"1.0\" encoding=\"UTF-8\"?><atc:runparameters xmlns:atc=\"http://www.sap.com/adt/atc\" xmlns:obj=\"http://www.sap.com/adt/objectset\" checkVariant=\"ABAP_CLOUD_DEVELOPMENT_DEFAULT\"><obj:objectSet><obj:softwarecomponents><obj:softwarecomponent value=\"Z_TEST\"/><obj:softwarecomponent value=\"/DMO/SWC\"/></obj:softwarecomponents></obj:objectSet></atc:runparameters>"
|
||||||
config := abapEnvironmentRunATCCheckOptions{
|
config := abapEnvironmentRunATCCheckOptions{
|
||||||
Repositories: "repo.yml",
|
Repositories: "repo.yml",
|
||||||
@@ -487,17 +479,15 @@ objectset:
|
|||||||
- name: /DMO/SWC
|
- name: /DMO/SWC
|
||||||
`
|
`
|
||||||
|
|
||||||
err := ioutil.WriteFile(config.Repositories, []byte(yamlBody), 0644)
|
err := ioutil.WriteFile(config.Repositories, []byte(yamlBody), 0o644)
|
||||||
if assert.Equal(t, err, nil) {
|
if assert.Equal(t, err, nil) {
|
||||||
bodyString, err := buildATCRequestBody(config)
|
bodyString, err := buildATCRequestBody(config)
|
||||||
assert.Equal(t, nil, err)
|
assert.Equal(t, nil, err)
|
||||||
assert.Equal(t, expectedBodyString, bodyString)
|
assert.Equal(t, expectedBodyString, bodyString)
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Missing config files", func(t *testing.T) {
|
t.Run("Missing config files", func(t *testing.T) {
|
||||||
|
|
||||||
config := abapEnvironmentRunATCCheckOptions{
|
config := abapEnvironmentRunATCCheckOptions{
|
||||||
AtcConfig: "atc.yml",
|
AtcConfig: "atc.yml",
|
||||||
}
|
}
|
||||||
@@ -505,16 +495,13 @@ objectset:
|
|||||||
bodyString, err := buildATCRequestBody(config)
|
bodyString, err := buildATCRequestBody(config)
|
||||||
assert.Equal(t, "Could not find atc.yml", err.Error())
|
assert.Equal(t, "Could not find atc.yml", err.Error())
|
||||||
assert.Equal(t, "", bodyString)
|
assert.Equal(t, "", bodyString)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("Config file not specified", func(t *testing.T) {
|
t.Run("Config file not specified", func(t *testing.T) {
|
||||||
|
|
||||||
config := abapEnvironmentRunATCCheckOptions{}
|
config := abapEnvironmentRunATCCheckOptions{}
|
||||||
|
|
||||||
bodyString, err := buildATCRequestBody(config)
|
bodyString, err := buildATCRequestBody(config)
|
||||||
assert.Equal(t, "No configuration provided - please provide either an ATC configuration file or a repository configuration file", err.Error())
|
assert.Equal(t, "No configuration provided - please provide either an ATC configuration file or a repository configuration file", err.Error())
|
||||||
assert.Equal(t, "", bodyString)
|
assert.Equal(t, "", bodyString)
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,15 +34,16 @@ func abapEnvironmentRunAUnitTest(config abapEnvironmentRunAUnitTestOptions, tele
|
|||||||
}
|
}
|
||||||
|
|
||||||
client := piperhttp.Client{}
|
client := piperhttp.Client{}
|
||||||
|
utils := piperutils.Files{}
|
||||||
|
|
||||||
// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end
|
// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end
|
||||||
err := runAbapEnvironmentRunAUnitTest(&config, telemetryData, &autils, &client)
|
err := runAbapEnvironmentRunAUnitTest(&config, telemetryData, &autils, &client, &utils)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Entry().WithError(err).Fatal("step execution failed")
|
log.Entry().WithError(err).Fatal("step execution failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func runAbapEnvironmentRunAUnitTest(config *abapEnvironmentRunAUnitTestOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client piperhttp.Sender) error {
|
func runAbapEnvironmentRunAUnitTest(config *abapEnvironmentRunAUnitTestOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client piperhttp.Sender, utils piperutils.FileUtils) error {
|
||||||
var details abaputils.ConnectionDetailsHTTP
|
var details abaputils.ConnectionDetailsHTTP
|
||||||
subOptions := convertAUnitOptions(config)
|
subOptions := convertAUnitOptions(config)
|
||||||
details, err := com.GetAbapCommunicationArrangementInfo(subOptions, "")
|
details, err := com.GetAbapCommunicationArrangementInfo(subOptions, "")
|
||||||
@@ -62,7 +63,7 @@ func runAbapEnvironmentRunAUnitTest(config *abapEnvironmentRunAUnitTestOptions,
|
|||||||
resp, err = triggerAUnitrun(*config, details, client)
|
resp, err = triggerAUnitrun(*config, details, client)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
err = fetchAndPersistAUnitResults(resp, details, client, config.AUnitResultsFileName, config.GenerateHTML)
|
err = fetchAndPersistAUnitResults(resp, details, client, utils, config.AUnitResultsFileName, config.GenerateHTML)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Entry().WithError(err).Fatal("step execution failed")
|
log.Entry().WithError(err).Fatal("step execution failed")
|
||||||
@@ -134,7 +135,7 @@ func convertAUnitOptions(options *abapEnvironmentRunAUnitTestOptions) abaputils.
|
|||||||
return subOptions
|
return subOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchAndPersistAUnitResults(resp *http.Response, details abaputils.ConnectionDetailsHTTP, client piperhttp.Sender, aunitResultFileName string, generateHTML bool) error {
|
func fetchAndPersistAUnitResults(resp *http.Response, details abaputils.ConnectionDetailsHTTP, client piperhttp.Sender, utils piperutils.FileUtils, aunitResultFileName string, generateHTML bool) error {
|
||||||
var err error
|
var err error
|
||||||
abapEndpoint := details.URL
|
abapEndpoint := details.URL
|
||||||
location := resp.Header.Get("Location")
|
location := resp.Header.Get("Location")
|
||||||
@@ -151,7 +152,7 @@ func fetchAndPersistAUnitResults(resp *http.Response, details abaputils.Connecti
|
|||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
err = persistAUnitResult(body, aunitResultFileName, generateHTML)
|
err = persistAUnitResult(utils, body, aunitResultFileName, generateHTML)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Handling AUnit result failed: %w", err)
|
return fmt.Errorf("Handling AUnit result failed: %w", err)
|
||||||
@@ -344,7 +345,7 @@ func getAUnitResults(requestType string, details abaputils.ConnectionDetailsHTTP
|
|||||||
return req, err
|
return req, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func persistAUnitResult(body []byte, aunitResultFileName string, generateHTML bool) (err error) {
|
func persistAUnitResult(utils piperutils.FileUtils, body []byte, aunitResultFileName string, generateHTML bool) (err error) {
|
||||||
if len(body) == 0 {
|
if len(body) == 0 {
|
||||||
return fmt.Errorf("Parsing AUnit result failed: %w", errors.New("Body is empty, can't parse empty body"))
|
return fmt.Errorf("Parsing AUnit result failed: %w", errors.New("Body is empty, can't parse empty body"))
|
||||||
}
|
}
|
||||||
@@ -396,7 +397,7 @@ func persistAUnitResult(body []byte, aunitResultFileName string, generateHTML bo
|
|||||||
}
|
}
|
||||||
//Persist findings afterwards
|
//Persist findings afterwards
|
||||||
reports = append(reports, piperutils.Path{Target: aunitResultFileName, Name: "AUnit Results", Mandatory: true})
|
reports = append(reports, piperutils.Path{Target: aunitResultFileName, Name: "AUnit Results", Mandatory: true})
|
||||||
piperutils.PersistReportsAndLinks("abapEnvironmentRunAUnitTest", "", reports, nil)
|
piperutils.PersistReportsAndLinks("abapEnvironmentRunAUnitTest", "", utils, reports, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -7,7 +7,6 @@ import (
|
|||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -36,6 +35,7 @@ type checkmarxExecuteScanUtils interface {
|
|||||||
Stat(name string) (os.FileInfo, error)
|
Stat(name string) (os.FileInfo, error)
|
||||||
Open(name string) (*os.File, error)
|
Open(name string) (*os.File, error)
|
||||||
WriteFile(filename string, data []byte, perm os.FileMode) error
|
WriteFile(filename string, data []byte, perm os.FileMode) error
|
||||||
|
MkdirAll(path string, perm os.FileMode) error
|
||||||
PathMatch(pattern, name string) (bool, error)
|
PathMatch(pattern, name string) (bool, error)
|
||||||
GetWorkspace() string
|
GetWorkspace() string
|
||||||
GetIssueService() *github.IssuesService
|
GetIssueService() *github.IssuesService
|
||||||
@@ -57,7 +57,11 @@ func (c *checkmarxExecuteScanUtilsBundle) GetWorkspace() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *checkmarxExecuteScanUtilsBundle) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
func (c *checkmarxExecuteScanUtilsBundle) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
return ioutil.WriteFile(filename, data, perm)
|
return os.WriteFile(filename, data, perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *checkmarxExecuteScanUtilsBundle) MkdirAll(path string, perm os.FileMode) error {
|
||||||
|
return os.MkdirAll(path, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *checkmarxExecuteScanUtilsBundle) FileInfoHeader(fi os.FileInfo) (*zip.FileHeader, error) {
|
func (c *checkmarxExecuteScanUtilsBundle) FileInfoHeader(fi os.FileInfo) (*zip.FileHeader, error) {
|
||||||
@@ -367,7 +371,7 @@ func verifyCxProjectCompliance(ctx context.Context, config checkmarxExecuteScanO
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create toolrecord
|
// create toolrecord
|
||||||
toolRecordFileName, err := createToolRecordCx(utils.GetWorkspace(), config, results)
|
toolRecordFileName, err := createToolRecordCx(utils, utils.GetWorkspace(), config, results)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// do not fail until the framework is well established
|
// do not fail until the framework is well established
|
||||||
log.Entry().Warning("TR_CHECKMARX: Failed to create toolrecord file ...", err)
|
log.Entry().Warning("TR_CHECKMARX: Failed to create toolrecord file ...", err)
|
||||||
@@ -417,7 +421,7 @@ func verifyCxProjectCompliance(ctx context.Context, config checkmarxExecuteScanO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
piperutils.PersistReportsAndLinks("checkmarxExecuteScan", utils.GetWorkspace(), reports, links)
|
piperutils.PersistReportsAndLinks("checkmarxExecuteScan", utils.GetWorkspace(), utils, reports, links)
|
||||||
reportToInflux(results, influx)
|
reportToInflux(results, influx)
|
||||||
|
|
||||||
if insecure {
|
if insecure {
|
||||||
@@ -962,8 +966,8 @@ func isFileNotMatchingPattern(patterns []string, path string, info os.FileInfo,
|
|||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createToolRecordCx(workspace string, config checkmarxExecuteScanOptions, results map[string]interface{}) (string, error) {
|
func createToolRecordCx(utils checkmarxExecuteScanUtils, workspace string, config checkmarxExecuteScanOptions, results map[string]interface{}) (string, error) {
|
||||||
record := toolrecord.New(workspace, "checkmarx", config.ServerURL)
|
record := toolrecord.New(utils, workspace, "checkmarx", config.ServerURL)
|
||||||
// Todo TeamId - see run_scan()
|
// Todo TeamId - see run_scan()
|
||||||
// record.AddKeyData("team", XXX, resultMap["Team"], "")
|
// record.AddKeyData("team", XXX, resultMap["Team"], "")
|
||||||
// Project
|
// Project
|
||||||
|
|||||||
@@ -321,6 +321,10 @@ func (c *checkmarxExecuteScanUtilsMock) WriteFile(filename string, data []byte,
|
|||||||
return ioutil.WriteFile(filename, data, perm)
|
return ioutil.WriteFile(filename, data, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *checkmarxExecuteScanUtilsMock) MkdirAll(path string, perm os.FileMode) error {
|
||||||
|
return os.MkdirAll(path, perm)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *checkmarxExecuteScanUtilsMock) FileInfoHeader(fi os.FileInfo) (*zip.FileHeader, error) {
|
func (c *checkmarxExecuteScanUtilsMock) FileInfoHeader(fi os.FileInfo) (*zip.FileHeader, error) {
|
||||||
if c.errorOnFileInfoHeader {
|
if c.errorOnFileInfoHeader {
|
||||||
return nil, fmt.Errorf("error on FileInfoHeader")
|
return nil, fmt.Errorf("error on FileInfoHeader")
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import (
|
|||||||
type codeqlExecuteScanUtils interface {
|
type codeqlExecuteScanUtils interface {
|
||||||
command.ExecRunner
|
command.ExecRunner
|
||||||
|
|
||||||
FileExists(filename string) (bool, error)
|
piperutils.FileUtils
|
||||||
}
|
}
|
||||||
|
|
||||||
type RepoInfo struct {
|
type RepoInfo struct {
|
||||||
@@ -226,7 +226,7 @@ func runCodeqlExecuteScan(config *codeqlExecuteScanOptions, telemetryData *telem
|
|||||||
|
|
||||||
reports = append(reports, piperutils.Path{Target: fmt.Sprintf("%vtarget/codeqlReport.csv", config.ModulePath)})
|
reports = append(reports, piperutils.Path{Target: fmt.Sprintf("%vtarget/codeqlReport.csv", config.ModulePath)})
|
||||||
|
|
||||||
piperutils.PersistReportsAndLinks("codeqlExecuteScan", "./", reports, nil)
|
piperutils.PersistReportsAndLinks("codeqlExecuteScan", "./", utils, reports, nil)
|
||||||
|
|
||||||
err = uploadResults(config, utils)
|
err = uploadResults(config, utils)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ func runDetect(ctx context.Context, config detectExecuteScanOptions, utils detec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// create Toolrecord file
|
// create Toolrecord file
|
||||||
toolRecordFileName, toolRecordErr := createToolRecordDetect("./", config, blackduckSystem)
|
toolRecordFileName, toolRecordErr := createToolRecordDetect(utils, "./", config, blackduckSystem)
|
||||||
if toolRecordErr != nil {
|
if toolRecordErr != nil {
|
||||||
// do not fail until the framework is well established
|
// do not fail until the framework is well established
|
||||||
log.Entry().Warning("TR_DETECT: Failed to create toolrecord file "+toolRecordFileName, err)
|
log.Entry().Warning("TR_DETECT: Failed to create toolrecord file "+toolRecordFileName, err)
|
||||||
@@ -538,7 +538,7 @@ func postScanChecksAndReporting(ctx context.Context, config detectExecuteScanOpt
|
|||||||
}
|
}
|
||||||
paths = append(paths, policyReportPaths...)
|
paths = append(paths, policyReportPaths...)
|
||||||
|
|
||||||
piperutils.PersistReportsAndLinks("detectExecuteScan", "", paths, nil)
|
piperutils.PersistReportsAndLinks("detectExecuteScan", "", utils, paths, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
errorsOccured = append(errorsOccured, fmt.Sprint(err))
|
||||||
}
|
}
|
||||||
@@ -719,8 +719,8 @@ func isActivePolicyViolation(status string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create toolrecord file for detectExecute
|
// create toolrecord file for detectExecute
|
||||||
func createToolRecordDetect(workspace string, config detectExecuteScanOptions, sys *blackduckSystem) (string, error) {
|
func createToolRecordDetect(utils detectUtils, workspace string, config detectExecuteScanOptions, sys *blackduckSystem) (string, error) {
|
||||||
record := toolrecord.New(workspace, "detectExecute", config.ServerURL)
|
record := toolrecord.New(utils, workspace, "detectExecute", config.ServerURL)
|
||||||
project, err := sys.Client.GetProject(config.ProjectName)
|
project, err := sys.Client.GetProject(config.ProjectName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("TR_DETECT: GetProject failed %v", err)
|
return "", fmt.Errorf("TR_DETECT: GetProject failed %v", err)
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ type pullRequestService interface {
|
|||||||
type fortifyUtils interface {
|
type fortifyUtils interface {
|
||||||
maven.Utils
|
maven.Utils
|
||||||
gradle.Utils
|
gradle.Utils
|
||||||
|
piperutils.FileUtils
|
||||||
|
|
||||||
SetDir(d string)
|
SetDir(d string)
|
||||||
GetArtifact(buildTool, buildDescriptorFile string, options *versioning.Options) (versioning.Artifact, error)
|
GetArtifact(buildTool, buildDescriptorFile string, options *versioning.Options) (versioning.Artifact, error)
|
||||||
@@ -122,7 +123,7 @@ func fortifyExecuteScan(config fortifyExecuteScanOptions, telemetryData *telemet
|
|||||||
|
|
||||||
influx.step_data.fields.fortify = false
|
influx.step_data.fields.fortify = false
|
||||||
reports, err := runFortifyScan(ctx, config, sys, utils, telemetryData, influx, auditStatus)
|
reports, err := runFortifyScan(ctx, config, sys, utils, telemetryData, influx, auditStatus)
|
||||||
piperutils.PersistReportsAndLinks("fortifyExecuteScan", config.ModulePath, reports, nil)
|
piperutils.PersistReportsAndLinks("fortifyExecuteScan", config.ModulePath, utils, reports, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Entry().WithError(err).Fatal("Fortify scan and check failed")
|
log.Entry().WithError(err).Fatal("Fortify scan and check failed")
|
||||||
}
|
}
|
||||||
@@ -229,7 +230,7 @@ func runFortifyScan(ctx context.Context, config fortifyExecuteScanOptions, sys f
|
|||||||
|
|
||||||
// create toolrecord file
|
// create toolrecord file
|
||||||
// tbd - how to handle verifyOnly
|
// tbd - how to handle verifyOnly
|
||||||
toolRecordFileName, err := createToolRecordFortify("./", config, project.ID, fortifyProjectName, projectVersion.ID, fortifyProjectVersion)
|
toolRecordFileName, err := createToolRecordFortify(utils, "./", config, project.ID, fortifyProjectName, projectVersion.ID, fortifyProjectVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// do not fail until the framework is well established
|
// do not fail until the framework is well established
|
||||||
log.Entry().Warning("TR_FORTIFY: Failed to create toolrecord file ...", err)
|
log.Entry().Warning("TR_FORTIFY: Failed to create toolrecord file ...", err)
|
||||||
@@ -1211,8 +1212,8 @@ func getSeparator() string {
|
|||||||
return ":"
|
return ":"
|
||||||
}
|
}
|
||||||
|
|
||||||
func createToolRecordFortify(workspace string, config fortifyExecuteScanOptions, projectID int64, projectName string, projectVersionID int64, projectVersion string) (string, error) {
|
func createToolRecordFortify(utils fortifyUtils, workspace string, config fortifyExecuteScanOptions, projectID int64, projectName string, projectVersionID int64, projectVersion string) (string, error) {
|
||||||
record := toolrecord.New(workspace, "fortify", config.ServerURL)
|
record := toolrecord.New(utils, workspace, "fortify", config.ServerURL)
|
||||||
// Project
|
// Project
|
||||||
err := record.AddKeyData("project",
|
err := record.AddKeyData("project",
|
||||||
strconv.FormatInt(projectID, 10),
|
strconv.FormatInt(projectID, 10),
|
||||||
|
|||||||
@@ -784,7 +784,7 @@ func (f filesMock) TempDir(dir string, pattern string) (name string, err error)
|
|||||||
if f.failOnCreation {
|
if f.failOnCreation {
|
||||||
return "", errors.New("error appeared")
|
return "", errors.New("error appeared")
|
||||||
}
|
}
|
||||||
return piperutils.Files{}.TempDir(dir, pattern)
|
return piperutils.Files{}.TempDir("", pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *filesMock) RemoveAll(path string) error {
|
func (f *filesMock) RemoveAll(path string) error {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const hadolintCommand = "hadolint"
|
|||||||
type HadolintPiperFileUtils interface {
|
type HadolintPiperFileUtils interface {
|
||||||
FileExists(filename string) (bool, error)
|
FileExists(filename string) (bool, error)
|
||||||
FileWrite(filename string, data []byte, perm os.FileMode) error
|
FileWrite(filename string, data []byte, perm os.FileMode) error
|
||||||
|
WriteFile(filename string, data []byte, perm os.FileMode) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// HadolintClient abstracts http.Client
|
// HadolintClient abstracts http.Client
|
||||||
@@ -114,7 +115,7 @@ func runHadolint(config hadolintExecuteOptions, utils hadolintUtils) error {
|
|||||||
}
|
}
|
||||||
//TODO: mock away in tests
|
//TODO: mock away in tests
|
||||||
// persist report information
|
// persist report information
|
||||||
piperutils.PersistReportsAndLinks("hadolintExecute", "./", []piperutils.Path{{Target: config.ReportFile}}, []piperutils.Path{})
|
piperutils.PersistReportsAndLinks("hadolintExecute", "./", utils, []piperutils.Path{{Target: config.ReportFile}}, []piperutils.Path{})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ func TestRunHadolintExecute(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fileMock.
|
fileMock.
|
||||||
On("FileExists", config.ConfigurationFile).Return(false, nil)
|
On("FileExists", config.ConfigurationFile).Return(false, nil).
|
||||||
|
On("WriteFile", "hadolintExecute_reports.json", mock.Anything, mock.Anything).Return(nil).
|
||||||
|
On("WriteFile", "hadolintExecute_links.json", mock.Anything, mock.Anything).Return(nil)
|
||||||
|
|
||||||
// test
|
// test
|
||||||
err := runHadolint(config, hadolintUtils{
|
err := runHadolint(config, hadolintUtils{
|
||||||
@@ -62,7 +64,11 @@ func TestRunHadolintExecute(t *testing.T) {
|
|||||||
// checks if config exists before downloading
|
// checks if config exists before downloading
|
||||||
On("FileExists", config.ConfigurationFile).Return(false, nil).Once().
|
On("FileExists", config.ConfigurationFile).Return(false, nil).Once().
|
||||||
// checks again but config is now downloaded
|
// checks again but config is now downloaded
|
||||||
On("FileExists", config.ConfigurationFile).Return(true, nil)
|
On("FileExists", config.ConfigurationFile).Return(true, nil).
|
||||||
|
On("WriteFile", "hadolintExecute_reports.json", mock.Anything, mock.Anything).Return(nil).
|
||||||
|
On("WriteFile", "hadolintExecute_links.json", mock.Anything, mock.Anything).Return(nil)
|
||||||
|
|
||||||
|
//m.On("Do", MatchedBy(func(req *http.Request) bool { return req.Host == "example.com" }))
|
||||||
// test
|
// test
|
||||||
err := runHadolint(config, hadolintUtils{
|
err := runHadolint(config, hadolintUtils{
|
||||||
HadolintPiperFileUtils: fileMock,
|
HadolintPiperFileUtils: fileMock,
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ func runMalwareScan(config *malwareExecuteScanOptions, telemetryData *telemetry.
|
|||||||
log.Entry().Infof("* Signatures: %s", scannerInfo.SignatureTimestamp)
|
log.Entry().Infof("* Signatures: %s", scannerInfo.SignatureTimestamp)
|
||||||
log.Entry().Infof("***************************************")
|
log.Entry().Infof("***************************************")
|
||||||
|
|
||||||
if _, err = createToolRecordMalwareScan("./", config, scannerInfo); err != nil {
|
if _, err = createToolRecordMalwareScan(utils, "./", config, scannerInfo); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,8 +187,8 @@ func validateHash(remoteHash, fileName string, utils malwareScanUtils) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create toolrecord file for malwarescan
|
// create toolrecord file for malwarescan
|
||||||
func createToolRecordMalwareScan(workspace string, config *malwareExecuteScanOptions, scanner *malwarescan.Info) (string, error) {
|
func createToolRecordMalwareScan(utils malwareScanUtils, workspace string, config *malwareExecuteScanOptions, scanner *malwarescan.Info) (string, error) {
|
||||||
record := toolrecord.New(workspace, "malwarescan", config.Host)
|
record := toolrecord.New(utils, workspace, "malwarescan", config.Host)
|
||||||
record.SetOverallDisplayData("Malware Scanner", "")
|
record.SetOverallDisplayData("Malware Scanner", "")
|
||||||
|
|
||||||
if err := record.AddKeyData("engineVersion", scanner.EngineVersion, "Engine Version", ""); err != nil {
|
if err := record.AddKeyData("engineVersion", scanner.EngineVersion, "Engine Version", ""); err != nil {
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ func executeProtecodeScan(influx *protecodeExecuteScanInflux, client protecode.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
// create toolrecord file
|
// create toolrecord file
|
||||||
toolRecordFileName, err := createToolRecordProtecode("./", config, productID, webuiURL)
|
toolRecordFileName, err := createToolRecordProtecode(utils, "./", config, productID, webuiURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// do not fail until the framework is well established
|
// do not fail until the framework is well established
|
||||||
log.Entry().Warning("TR_PROTECODE: Failed to create toolrecord file ...", err)
|
log.Entry().Warning("TR_PROTECODE: Failed to create toolrecord file ...", err)
|
||||||
@@ -276,7 +276,7 @@ func executeProtecodeScan(influx *protecodeExecuteScanInflux, client protecode.P
|
|||||||
reports = append(reports, piperutils.Path{Target: toolRecordFileName})
|
reports = append(reports, piperutils.Path{Target: toolRecordFileName})
|
||||||
}
|
}
|
||||||
|
|
||||||
piperutils.PersistReportsAndLinks("protecodeExecuteScan", "", reports, links)
|
piperutils.PersistReportsAndLinks("protecodeExecuteScan", "", utils, reports, links)
|
||||||
|
|
||||||
if config.FailOnSevereVulnerabilities && protecode.HasSevereVulnerabilities(result.Result, config.ExcludeCVEs) {
|
if config.FailOnSevereVulnerabilities && protecode.HasSevereVulnerabilities(result.Result, config.ExcludeCVEs) {
|
||||||
log.SetErrorCategory(log.ErrorCompliance)
|
log.SetErrorCategory(log.ErrorCompliance)
|
||||||
@@ -418,8 +418,8 @@ func getProcessedVersion(config *protecodeExecuteScanOptions) string {
|
|||||||
|
|
||||||
// create toolrecord file for protecode
|
// create toolrecord file for protecode
|
||||||
// todo: check if group and product names can be retrieved
|
// todo: check if group and product names can be retrieved
|
||||||
func createToolRecordProtecode(workspace string, config *protecodeExecuteScanOptions, productID int, webuiURL string) (string, error) {
|
func createToolRecordProtecode(utils protecodeUtils, workspace string, config *protecodeExecuteScanOptions, productID int, webuiURL string) (string, error) {
|
||||||
record := toolrecord.New(workspace, "protecode", config.ServerURL)
|
record := toolrecord.New(utils, workspace, "protecode", config.ServerURL)
|
||||||
groupURL := config.ServerURL + "/#/groups/" + config.Group
|
groupURL := config.ServerURL + "/#/groups/" + config.Group
|
||||||
err := record.AddKeyData("group",
|
err := record.AddKeyData("group",
|
||||||
config.Group,
|
config.Group,
|
||||||
|
|||||||
+10
-11
@@ -18,9 +18,7 @@ import (
|
|||||||
keytool "github.com/SAP/jenkins-library/pkg/java"
|
keytool "github.com/SAP/jenkins-library/pkg/java"
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
"github.com/SAP/jenkins-library/pkg/orchestrator"
|
"github.com/SAP/jenkins-library/pkg/orchestrator"
|
||||||
FileUtils "github.com/SAP/jenkins-library/pkg/piperutils"
|
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||||
SliceUtils "github.com/SAP/jenkins-library/pkg/piperutils"
|
|
||||||
StepResults "github.com/SAP/jenkins-library/pkg/piperutils"
|
|
||||||
SonarUtils "github.com/SAP/jenkins-library/pkg/sonar"
|
SonarUtils "github.com/SAP/jenkins-library/pkg/sonar"
|
||||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||||
"github.com/SAP/jenkins-library/pkg/versioning"
|
"github.com/SAP/jenkins-library/pkg/versioning"
|
||||||
@@ -45,8 +43,8 @@ var (
|
|||||||
sonar sonarSettings
|
sonar sonarSettings
|
||||||
|
|
||||||
execLookPath = exec.LookPath
|
execLookPath = exec.LookPath
|
||||||
fileUtilsExists = FileUtils.FileExists
|
fileUtilsExists = piperutils.FileExists
|
||||||
fileUtilsUnzip = FileUtils.Unzip
|
fileUtilsUnzip = piperutils.Unzip
|
||||||
osRename = os.Rename
|
osRename = os.Rename
|
||||||
osStat = os.Stat
|
osStat = os.Stat
|
||||||
doublestarGlob = doublestar.Glob
|
doublestarGlob = doublestar.Glob
|
||||||
@@ -95,7 +93,8 @@ func sonarExecuteScan(config sonarExecuteScanOptions, _ *telemetry.CustomData, i
|
|||||||
}
|
}
|
||||||
|
|
||||||
influx.step_data.fields.sonar = false
|
influx.step_data.fields.sonar = false
|
||||||
if err := runSonar(config, downloadClient, &runner, apiClient, influx); err != nil {
|
fileUtils := piperutils.Files{}
|
||||||
|
if err := runSonar(config, downloadClient, &runner, apiClient, &fileUtils, influx); err != nil {
|
||||||
if log.GetErrorCategory() == log.ErrorUndefined && runner.GetExitCode() == 2 {
|
if log.GetErrorCategory() == log.ErrorUndefined && runner.GetExitCode() == 2 {
|
||||||
// see https://github.com/SonarSource/sonar-scanner-cli/blob/adb67d645c3bcb9b46f29dea06ba082ebec9ba7a/src/main/java/org/sonarsource/scanner/cli/Exit.java#L25
|
// see https://github.com/SonarSource/sonar-scanner-cli/blob/adb67d645c3bcb9b46f29dea06ba082ebec9ba7a/src/main/java/org/sonarsource/scanner/cli/Exit.java#L25
|
||||||
log.SetErrorCategory(log.ErrorConfiguration)
|
log.SetErrorCategory(log.ErrorConfiguration)
|
||||||
@@ -105,7 +104,7 @@ func sonarExecuteScan(config sonarExecuteScanOptions, _ *telemetry.CustomData, i
|
|||||||
influx.step_data.fields.sonar = true
|
influx.step_data.fields.sonar = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func runSonar(config sonarExecuteScanOptions, client piperhttp.Downloader, runner command.ExecRunner, apiClient SonarUtils.Sender, influx *sonarExecuteScanInflux) error {
|
func runSonar(config sonarExecuteScanOptions, client piperhttp.Downloader, runner command.ExecRunner, apiClient SonarUtils.Sender, utils piperutils.FileUtils, influx *sonarExecuteScanInflux) error {
|
||||||
// Set config based on orchestrator-specific environment variables
|
// Set config based on orchestrator-specific environment variables
|
||||||
detectParametersFromCI(&config)
|
detectParametersFromCI(&config)
|
||||||
|
|
||||||
@@ -168,7 +167,7 @@ func runSonar(config sonarExecuteScanOptions, client piperhttp.Downloader, runne
|
|||||||
sonar.options = append(sonar.options, config.Options...)
|
sonar.options = append(sonar.options, config.Options...)
|
||||||
}
|
}
|
||||||
|
|
||||||
sonar.options = SliceUtils.PrefixIfNeeded(SliceUtils.Trim(sonar.options), "-D")
|
sonar.options = piperutils.PrefixIfNeeded(piperutils.Trim(sonar.options), "-D")
|
||||||
|
|
||||||
log.Entry().
|
log.Entry().
|
||||||
WithField("command", sonar.binary).
|
WithField("command", sonar.binary).
|
||||||
@@ -194,13 +193,13 @@ func runSonar(config sonarExecuteScanOptions, client piperhttp.Downloader, runne
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// write links JSON
|
// write links JSON
|
||||||
links := []StepResults.Path{
|
links := []piperutils.Path{
|
||||||
{
|
{
|
||||||
Target: taskReport.DashboardURL,
|
Target: taskReport.DashboardURL,
|
||||||
Name: "Sonar Web UI",
|
Name: "Sonar Web UI",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
StepResults.PersistReportsAndLinks("sonarExecuteScan", sonar.workingDir, nil, links)
|
piperutils.PersistReportsAndLinks("sonarExecuteScan", sonar.workingDir, utils, nil, links)
|
||||||
|
|
||||||
if len(config.Token) == 0 {
|
if len(config.Token) == 0 {
|
||||||
log.Entry().Warn("no measurements are fetched due to missing credentials")
|
log.Entry().Warn("no measurements are fetched due to missing credentials")
|
||||||
@@ -278,7 +277,7 @@ func runSonar(config sonarExecuteScanOptions, client piperhttp.Downloader, runne
|
|||||||
// isInOptions returns true, if the given property is already provided in config.Options.
|
// isInOptions returns true, if the given property is already provided in config.Options.
|
||||||
func isInOptions(config sonarExecuteScanOptions, property string) bool {
|
func isInOptions(config sonarExecuteScanOptions, property string) bool {
|
||||||
property = strings.TrimSuffix(property, "=")
|
property = strings.TrimSuffix(property, "=")
|
||||||
return SliceUtils.ContainsStringPart(config.Options, property)
|
return piperutils.ContainsStringPart(config.Options, property)
|
||||||
}
|
}
|
||||||
|
|
||||||
func addJavaBinaries() {
|
func addJavaBinaries() {
|
||||||
|
|||||||
@@ -17,11 +17,11 @@ import (
|
|||||||
|
|
||||||
piperHttp "github.com/SAP/jenkins-library/pkg/http"
|
piperHttp "github.com/SAP/jenkins-library/pkg/http"
|
||||||
"github.com/SAP/jenkins-library/pkg/mock"
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
FileUtils "github.com/SAP/jenkins-library/pkg/piperutils"
|
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||||
SonarUtils "github.com/SAP/jenkins-library/pkg/sonar"
|
SonarUtils "github.com/SAP/jenkins-library/pkg/sonar"
|
||||||
)
|
)
|
||||||
|
|
||||||
//TODO: extract to mock package
|
// TODO: extract to mock package
|
||||||
type mockDownloader struct {
|
type mockDownloader struct {
|
||||||
shouldFail bool
|
shouldFail bool
|
||||||
requestedURL []string
|
requestedURL []string
|
||||||
@@ -92,8 +92,8 @@ func mockGlob(matchesForPatterns map[string][]string) func(pattern string) ([]st
|
|||||||
}
|
}
|
||||||
|
|
||||||
func createTaskReportFile(t *testing.T, workingDir string) {
|
func createTaskReportFile(t *testing.T, workingDir string) {
|
||||||
require.NoError(t, os.MkdirAll(filepath.Join(workingDir, ".scannerwork"), 0755))
|
require.NoError(t, os.MkdirAll(filepath.Join(workingDir, ".scannerwork"), 0o755))
|
||||||
require.NoError(t, ioutil.WriteFile(filepath.Join(workingDir, ".scannerwork", "report-task.txt"), []byte(taskReportContent), 0755))
|
require.NoError(t, ioutil.WriteFile(filepath.Join(workingDir, ".scannerwork", "report-task.txt"), []byte(taskReportContent), 0o755))
|
||||||
require.FileExists(t, filepath.Join(workingDir, ".scannerwork", "report-task.txt"))
|
require.FileExists(t, filepath.Join(workingDir, ".scannerwork", "report-task.txt"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,7 +175,7 @@ func TestRunSonar(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fileUtilsExists = mockFileUtilsExists(true)
|
fileUtilsExists = mockFileUtilsExists(true)
|
||||||
// test
|
// test
|
||||||
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &sonarExecuteScanInflux{})
|
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &mock.FilesMock{}, &sonarExecuteScanInflux{})
|
||||||
// assert
|
// assert
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, sonar.options, "-Dsonar.projectVersion=1")
|
assert.Contains(t, sonar.options, "-Dsonar.projectVersion=1")
|
||||||
@@ -183,8 +183,6 @@ func TestRunSonar(t *testing.T) {
|
|||||||
assert.Contains(t, sonar.environment, "SONAR_HOST_URL="+sonarServerURL)
|
assert.Contains(t, sonar.environment, "SONAR_HOST_URL="+sonarServerURL)
|
||||||
assert.Contains(t, sonar.environment, "SONAR_TOKEN=secret-ABC")
|
assert.Contains(t, sonar.environment, "SONAR_TOKEN=secret-ABC")
|
||||||
assert.Contains(t, sonar.environment, "SONAR_SCANNER_OPTS=-Djavax.net.ssl.trustStore="+filepath.Join(getWorkingDir(), ".certificates", "cacerts")+" -Djavax.net.ssl.trustStorePassword=changeit")
|
assert.Contains(t, sonar.environment, "SONAR_SCANNER_OPTS=-Djavax.net.ssl.trustStore="+filepath.Join(getWorkingDir(), ".certificates", "cacerts")+" -Djavax.net.ssl.trustStorePassword=changeit")
|
||||||
assert.FileExists(t, filepath.Join(sonar.workingDir, "sonarExecuteScan_reports.json"))
|
|
||||||
assert.FileExists(t, filepath.Join(sonar.workingDir, "sonarExecuteScan_links.json"))
|
|
||||||
})
|
})
|
||||||
t.Run("with custom options", func(t *testing.T) {
|
t.Run("with custom options", func(t *testing.T) {
|
||||||
// init
|
// init
|
||||||
@@ -203,10 +201,10 @@ func TestRunSonar(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fileUtilsExists = mockFileUtilsExists(true)
|
fileUtilsExists = mockFileUtilsExists(true)
|
||||||
defer func() {
|
defer func() {
|
||||||
fileUtilsExists = FileUtils.FileExists
|
fileUtilsExists = piperutils.FileExists
|
||||||
}()
|
}()
|
||||||
// test
|
// test
|
||||||
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &sonarExecuteScanInflux{})
|
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &mock.FilesMock{}, &sonarExecuteScanInflux{})
|
||||||
// assert
|
// assert
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, sonar.options, "-Dsonar.projectKey=piper")
|
assert.Contains(t, sonar.options, "-Dsonar.projectKey=piper")
|
||||||
@@ -235,7 +233,7 @@ func TestRunSonar(t *testing.T) {
|
|||||||
osStat = mockOsStat(existsMap)
|
osStat = mockOsStat(existsMap)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
fileUtilsExists = FileUtils.FileExists
|
fileUtilsExists = piperutils.FileExists
|
||||||
doublestarGlob = doublestar.Glob
|
doublestarGlob = doublestar.Glob
|
||||||
osStat = os.Stat
|
osStat = os.Stat
|
||||||
}()
|
}()
|
||||||
@@ -244,7 +242,7 @@ func TestRunSonar(t *testing.T) {
|
|||||||
PullRequestProvider: "GitHub",
|
PullRequestProvider: "GitHub",
|
||||||
}
|
}
|
||||||
// test
|
// test
|
||||||
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &sonarExecuteScanInflux{})
|
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &mock.FilesMock{}, &sonarExecuteScanInflux{})
|
||||||
// assert
|
// assert
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, sonar.options, fmt.Sprintf("-Dsonar.java.binaries=%s,%s,%s",
|
assert.Contains(t, sonar.options, fmt.Sprintf("-Dsonar.java.binaries=%s,%s,%s",
|
||||||
@@ -274,7 +272,7 @@ func TestRunSonar(t *testing.T) {
|
|||||||
osStat = mockOsStat(existsMap)
|
osStat = mockOsStat(existsMap)
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
fileUtilsExists = FileUtils.FileExists
|
fileUtilsExists = piperutils.FileExists
|
||||||
doublestarGlob = doublestar.Glob
|
doublestarGlob = doublestar.Glob
|
||||||
osStat = os.Stat
|
osStat = os.Stat
|
||||||
}()
|
}()
|
||||||
@@ -284,7 +282,7 @@ func TestRunSonar(t *testing.T) {
|
|||||||
PullRequestProvider: "GitHub",
|
PullRequestProvider: "GitHub",
|
||||||
}
|
}
|
||||||
// test
|
// test
|
||||||
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &sonarExecuteScanInflux{})
|
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &mock.FilesMock{}, &sonarExecuteScanInflux{})
|
||||||
// assert
|
// assert
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotContains(t, sonar.options, fmt.Sprintf("-Dsonar.java.binaries=%s",
|
assert.NotContains(t, sonar.options, fmt.Sprintf("-Dsonar.java.binaries=%s",
|
||||||
@@ -313,10 +311,10 @@ func TestRunSonar(t *testing.T) {
|
|||||||
defer func() { GeneralConfig.Verbose = false }()
|
defer func() { GeneralConfig.Verbose = false }()
|
||||||
fileUtilsExists = mockFileUtilsExists(true)
|
fileUtilsExists = mockFileUtilsExists(true)
|
||||||
defer func() {
|
defer func() {
|
||||||
fileUtilsExists = FileUtils.FileExists
|
fileUtilsExists = piperutils.FileExists
|
||||||
}()
|
}()
|
||||||
// test
|
// test
|
||||||
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &sonarExecuteScanInflux{})
|
err := runSonar(options, &mockDownloadClient, &mockRunner, apiClient, &mock.FilesMock{}, &sonarExecuteScanInflux{})
|
||||||
// assert
|
// assert
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Contains(t, sonar.options, "-Dsonar.projectKey=mock-project-key")
|
assert.Contains(t, sonar.options, "-Dsonar.projectKey=mock-project-key")
|
||||||
@@ -430,7 +428,7 @@ func TestSonarLoadScanner(t *testing.T) {
|
|||||||
osRename = mockOsRename(t, "sonar-scanner-4.6.2.2472-linux", ".sonar-scanner")
|
osRename = mockOsRename(t, "sonar-scanner-4.6.2.2472-linux", ".sonar-scanner")
|
||||||
defer func() {
|
defer func() {
|
||||||
execLookPath = exec.LookPath
|
execLookPath = exec.LookPath
|
||||||
fileUtilsUnzip = FileUtils.Unzip
|
fileUtilsUnzip = piperutils.Unzip
|
||||||
osRename = os.Rename
|
osRename = os.Rename
|
||||||
}()
|
}()
|
||||||
// test
|
// test
|
||||||
@@ -455,7 +453,7 @@ func TestSonarLoadCertificates(t *testing.T) {
|
|||||||
options: []string{},
|
options: []string{},
|
||||||
}
|
}
|
||||||
fileUtilsExists = mockFileUtilsExists(true)
|
fileUtilsExists = mockFileUtilsExists(true)
|
||||||
defer func() { fileUtilsExists = FileUtils.FileExists }()
|
defer func() { fileUtilsExists = piperutils.FileExists }()
|
||||||
// test
|
// test
|
||||||
err := loadCertificates([]string{}, &mockClient, &mockRunner)
|
err := loadCertificates([]string{}, &mockClient, &mockRunner)
|
||||||
// assert
|
// assert
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ func runWhitesourceScan(ctx context.Context, config *ScanOptions, scan *ws.Scan,
|
|||||||
log.Entry().Info("-----------------------------------------------------")
|
log.Entry().Info("-----------------------------------------------------")
|
||||||
|
|
||||||
paths, err := checkAndReportScanResults(ctx, config, scan, utils, sys, influx)
|
paths, err := checkAndReportScanResults(ctx, config, scan, utils, sys, influx)
|
||||||
piperutils.PersistReportsAndLinks("whitesourceExecuteScan", "", paths, nil)
|
piperutils.PersistReportsAndLinks("whitesourceExecuteScan", "", utils, paths, nil)
|
||||||
persistScannedProjects(config, scan, commonPipelineEnvironment)
|
persistScannedProjects(config, scan, commonPipelineEnvironment)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "failed to check and report scan results")
|
return errors.Wrapf(err, "failed to check and report scan results")
|
||||||
@@ -273,7 +273,7 @@ func checkAndReportScanResults(ctx context.Context, config *ScanOptions, scan *w
|
|||||||
|
|
||||||
// create toolrecord file
|
// create toolrecord file
|
||||||
// tbd - how to handle verifyOnly
|
// tbd - how to handle verifyOnly
|
||||||
toolRecordFileName, err := createToolRecordWhitesource("./", config, scan)
|
toolRecordFileName, err := createToolRecordWhitesource(utils, "./", config, scan)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// do not fail until the framework is well established
|
// do not fail until the framework is well established
|
||||||
log.Entry().Warning("TR_WHITESOURCE: Failed to create toolrecord file ...", err)
|
log.Entry().Warning("TR_WHITESOURCE: Failed to create toolrecord file ...", err)
|
||||||
@@ -750,7 +750,7 @@ func newVulnerabilityExcelReport(alerts []ws.Alert, config *ScanOptions, utils w
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
filePath := piperutils.Path{Name: "aggregated-vulnerabilities", Target: fileName}
|
filePath := piperutils.Path{Name: "aggregated-vulnerabilities", Target: fileName}
|
||||||
piperutils.PersistReportsAndLinks("whitesourceExecuteScan", "", []piperutils.Path{filePath}, nil)
|
piperutils.PersistReportsAndLinks("whitesourceExecuteScan", "", utils, []piperutils.Path{filePath}, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -812,7 +812,7 @@ func newLibraryCSVReport(libraries map[string][]ws.Library, config *ScanOptions,
|
|||||||
return errors.Wrapf(err, "failed to write file: %s", fileName)
|
return errors.Wrapf(err, "failed to write file: %s", fileName)
|
||||||
}
|
}
|
||||||
filePath := piperutils.Path{Name: "aggregated-libraries", Target: fileName}
|
filePath := piperutils.Path{Name: "aggregated-libraries", Target: fileName}
|
||||||
piperutils.PersistReportsAndLinks("whitesourceExecuteScan", "", []piperutils.Path{filePath}, nil)
|
piperutils.PersistReportsAndLinks("whitesourceExecuteScan", "", utils, []piperutils.Path{filePath}, nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -830,8 +830,8 @@ func persistScannedProjects(config *ScanOptions, scan *ws.Scan, commonPipelineEn
|
|||||||
|
|
||||||
// create toolrecord file for whitesource
|
// create toolrecord file for whitesource
|
||||||
//
|
//
|
||||||
func createToolRecordWhitesource(workspace string, config *whitesourceExecuteScanOptions, scan *ws.Scan) (string, error) {
|
func createToolRecordWhitesource(utils whitesourceUtils, workspace string, config *whitesourceExecuteScanOptions, scan *ws.Scan) (string, error) {
|
||||||
record := toolrecord.New(workspace, "whitesource", config.ServiceURL)
|
record := toolrecord.New(utils, workspace, "whitesource", config.ServiceURL)
|
||||||
wsUiRoot := "https://saas.whitesourcesoftware.com"
|
wsUiRoot := "https://saas.whitesourcesoftware.com"
|
||||||
productURL := wsUiRoot + "/Wss/WSS.html#!product;token=" + config.ProductToken
|
productURL := wsUiRoot + "/Wss/WSS.html#!product;token=" + config.ProductToken
|
||||||
err := record.AddKeyData("product",
|
err := record.AddKeyData("product",
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/mock"
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
"github.com/SAP/jenkins-library/pkg/piperenv"
|
|
||||||
"github.com/SAP/jenkins-library/pkg/piperutils"
|
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||||
"github.com/SAP/jenkins-library/pkg/reporting"
|
"github.com/SAP/jenkins-library/pkg/reporting"
|
||||||
"github.com/SAP/jenkins-library/pkg/versioning"
|
"github.com/SAP/jenkins-library/pkg/versioning"
|
||||||
@@ -663,7 +662,8 @@ func TestAggregateVersionWideLibraries(t *testing.T) {
|
|||||||
contents, _ := utils.FileRead(resource)
|
contents, _ := utils.FileRead(resource)
|
||||||
asString := string(contents)
|
asString := string(contents)
|
||||||
assert.Equal(t, "Library Name, Project Name\nmock-library, mock-project\n", asString)
|
assert.Equal(t, "Library Name, Project Name\nmock-library, mock-project\n", asString)
|
||||||
assert.NotEmpty(t, piperenv.GetParameter("", "whitesourceExecuteScan_reports.json"))
|
c, _ := utils.ReadFile("/whitesourceExecuteScan_reports.json")
|
||||||
|
assert.NotEmpty(t, c)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -692,7 +692,8 @@ func TestAggregateVersionWideVulnerabilities(t *testing.T) {
|
|||||||
sheetContents, err := utils.FileRead(reportSheet)
|
sheetContents, err := utils.FileRead(reportSheet)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.NotEmpty(t, sheetContents)
|
assert.NotEmpty(t, sheetContents)
|
||||||
assert.NotEmpty(t, piperenv.GetParameter("", "whitesourceExecuteScan_reports.json"))
|
c, _ := utils.ReadFile("whitesourceExecuteScan_reports.json")
|
||||||
|
assert.NotEmpty(t, c)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,11 +8,13 @@ import (
|
|||||||
"github.com/SAP/jenkins-library/pkg/command"
|
"github.com/SAP/jenkins-library/pkg/command"
|
||||||
piperhttp "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/log"
|
||||||
|
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AakUtils interface {
|
type AakUtils interface {
|
||||||
command.ExecRunner
|
command.ExecRunner
|
||||||
abapbuild.HTTPSendLoader
|
abapbuild.HTTPSendLoader
|
||||||
|
piperutils.FileUtils
|
||||||
ReadAddonDescriptor(FileName string) (abaputils.AddonDescriptor, error)
|
ReadAddonDescriptor(FileName string) (abaputils.AddonDescriptor, error)
|
||||||
GetMaxRuntime() time.Duration
|
GetMaxRuntime() time.Duration
|
||||||
GetPollingInterval() time.Duration
|
GetPollingInterval() time.Duration
|
||||||
@@ -21,6 +23,7 @@ type AakUtils interface {
|
|||||||
type AakBundle struct {
|
type AakBundle struct {
|
||||||
*command.Command
|
*command.Command
|
||||||
*piperhttp.Client
|
*piperhttp.Client
|
||||||
|
*piperutils.Files
|
||||||
maxRuntime time.Duration
|
maxRuntime time.Duration
|
||||||
pollingInterval time.Duration
|
pollingInterval time.Duration
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,12 +9,14 @@ import (
|
|||||||
abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
|
abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
|
||||||
"github.com/SAP/jenkins-library/pkg/abaputils"
|
"github.com/SAP/jenkins-library/pkg/abaputils"
|
||||||
"github.com/SAP/jenkins-library/pkg/mock"
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
|
"github.com/SAP/jenkins-library/pkg/piperutils"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AakBundleMock struct {
|
type AakBundleMock struct {
|
||||||
*mock.ExecMockRunner
|
*mock.ExecMockRunner
|
||||||
*abaputils.ClientMock
|
*abaputils.ClientMock
|
||||||
|
*mock.FilesMock
|
||||||
maxRuntime time.Duration
|
maxRuntime time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,6 +25,7 @@ func NewAakBundleMock() *AakBundleMock {
|
|||||||
ExecMockRunner: &mock.ExecMockRunner{},
|
ExecMockRunner: &mock.ExecMockRunner{},
|
||||||
ClientMock: &abaputils.ClientMock{},
|
ClientMock: &abaputils.ClientMock{},
|
||||||
maxRuntime: 1 * time.Second,
|
maxRuntime: 1 * time.Second,
|
||||||
|
FilesMock: &mock.FilesMock{},
|
||||||
}
|
}
|
||||||
return &utils
|
return &utils
|
||||||
}
|
}
|
||||||
@@ -100,6 +103,7 @@ func (bundle *AakBundleMock) ReadAddonDescriptor(FileName string) (abaputils.Add
|
|||||||
type AakBundleMockNewMC struct {
|
type AakBundleMockNewMC struct {
|
||||||
*mock.ExecMockRunner
|
*mock.ExecMockRunner
|
||||||
*abapbuild.MockClient
|
*abapbuild.MockClient
|
||||||
|
*piperutils.Files
|
||||||
maxRuntime time.Duration
|
maxRuntime time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-13
@@ -440,7 +440,7 @@ func (b *Build) DownloadResults(filenames []string, basePath string, filenamePre
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PublishAllDownloadedResults : publishes all build artefacts which were downloaded before
|
// PublishAllDownloadedResults : publishes all build artefacts which were downloaded before
|
||||||
func (b *Build) PublishAllDownloadedResults(stepname string, publish Publish) {
|
func (b *Build) PublishAllDownloadedResults(stepname string, utils piperutils.FileUtils) {
|
||||||
var filesToPublish []piperutils.Path
|
var filesToPublish []piperutils.Path
|
||||||
for i_task := range b.Tasks {
|
for i_task := range b.Tasks {
|
||||||
for i_result := range b.Tasks[i_task].Results {
|
for i_result := range b.Tasks[i_task].Results {
|
||||||
@@ -451,12 +451,14 @@ func (b *Build) PublishAllDownloadedResults(stepname string, publish Publish) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(filesToPublish) > 0 {
|
if len(filesToPublish) > 0 {
|
||||||
publish.PersistReportsAndLinks(stepname, "", filesToPublish, nil)
|
if err := piperutils.PersistReportsAndLinks(stepname, "", utils, filesToPublish, nil); err != nil {
|
||||||
|
log.Entry().WithError(err).Error("failed to persist reports")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// PublishDownloadedResults : Publishes build artefacts specified in filenames
|
// PublishDownloadedResults : Publishes build artefacts specified in filenames
|
||||||
func (b *Build) PublishDownloadedResults(stepname string, filenames []string, publish Publish) error {
|
func (b *Build) PublishDownloadedResults(stepname string, filenames []string, utils piperutils.FileUtils) error {
|
||||||
var filesToPublish []piperutils.Path
|
var filesToPublish []piperutils.Path
|
||||||
for i := range filenames {
|
for i := range filenames {
|
||||||
result, err := b.GetResult(filenames[i])
|
result, err := b.GetResult(filenames[i])
|
||||||
@@ -472,7 +474,9 @@ func (b *Build) PublishDownloadedResults(stepname string, filenames []string, pu
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(filesToPublish) > 0 {
|
if len(filesToPublish) > 0 {
|
||||||
publish.PersistReportsAndLinks(stepname, "", filesToPublish, nil)
|
if err := piperutils.PersistReportsAndLinks(stepname, "", utils, filesToPublish, nil); err != nil {
|
||||||
|
log.Entry().WithError(err).Error("failed to persist reports")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -594,12 +598,3 @@ func unmarshalTasks(body []byte, connector Connector) ([]task, error) {
|
|||||||
}
|
}
|
||||||
return tasks, nil
|
return tasks, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// *****************publish *******************************
|
|
||||||
type Publish interface {
|
|
||||||
PersistReportsAndLinks(stepName, workspace string, reports, links []piperutils.Path)
|
|
||||||
}
|
|
||||||
|
|
||||||
func PersistReportsAndLinks(stepName, workspace string, reports, links []piperutils.Path) {
|
|
||||||
piperutils.PersistReportsAndLinks(stepName, workspace, reports, links)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -34,8 +34,7 @@ func (c *ClMock) SetOptions(opts piperhttp.ClientOptions) {}
|
|||||||
// SendRequest : BF Send Fake request
|
// SendRequest : BF Send Fake request
|
||||||
func (c *ClMock) SendRequest(method string, url string, bdy io.Reader, hdr http.Header, cookies []*http.Cookie) (*http.Response, error) {
|
func (c *ClMock) SendRequest(method string, url string, bdy io.Reader, hdr http.Header, cookies []*http.Cookie) (*http.Response, error) {
|
||||||
if method == "GET" || method == "POST" {
|
if method == "GET" || method == "POST" {
|
||||||
var body []byte
|
body := []byte(fakeResponse(method, url))
|
||||||
body = []byte(fakeResponse(method, url))
|
|
||||||
return &http.Response{
|
return &http.Response{
|
||||||
StatusCode: c.StatusCode,
|
StatusCode: c.StatusCode,
|
||||||
Body: ioutil.NopCloser(bytes.NewReader(body)),
|
Body: ioutil.NopCloser(bytes.NewReader(body)),
|
||||||
|
|||||||
+17
-44
@@ -7,18 +7,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||||
"github.com/SAP/jenkins-library/pkg/piperutils"
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockPublish struct {
|
|
||||||
reports []piperutils.Path
|
|
||||||
}
|
|
||||||
|
|
||||||
func (mP *mockPublish) PersistReportsAndLinks(stepName, workspace string, reports, links []piperutils.Path) {
|
|
||||||
mP.reports = reports
|
|
||||||
}
|
|
||||||
|
|
||||||
func testSetup(client piperhttp.Sender, buildID string) Build {
|
func testSetup(client piperhttp.Sender, buildID string) Build {
|
||||||
conn := new(Connector)
|
conn := new(Connector)
|
||||||
conn.Client = client
|
conn.Client = client
|
||||||
@@ -370,36 +362,26 @@ func TestPublishAllDownloadedResults(t *testing.T) {
|
|||||||
t.Run("Something was downloaded", func(t *testing.T) {
|
t.Run("Something was downloaded", func(t *testing.T) {
|
||||||
//arrange
|
//arrange
|
||||||
build := GetMockBuildTestDownloadPublish()
|
build := GetMockBuildTestDownloadPublish()
|
||||||
mP := mockPublish{}
|
files := mock.FilesMock{}
|
||||||
build.Tasks[1].Results[0].SavedFilename = "File1"
|
build.Tasks[1].Results[0].SavedFilename = "File1"
|
||||||
build.Tasks[1].Results[0].DownloadPath = "Dir1/File1"
|
build.Tasks[1].Results[0].DownloadPath = "Dir1/File1"
|
||||||
build.Tasks[1].Results[2].SavedFilename = "File3"
|
build.Tasks[1].Results[2].SavedFilename = "File3"
|
||||||
build.Tasks[1].Results[2].DownloadPath = "File3"
|
build.Tasks[1].Results[2].DownloadPath = "File3"
|
||||||
//act
|
//act
|
||||||
build.PublishAllDownloadedResults("MyStep", &mP)
|
build.PublishAllDownloadedResults("MyStep", &files)
|
||||||
//assert
|
//assert
|
||||||
publishedFiles := []piperutils.Path{
|
assert.True(t, files.HasFile("/MyStep_reports.json"))
|
||||||
{
|
assert.True(t, files.HasFile("/MyStep_links.json"))
|
||||||
Target: "Dir1/File1",
|
|
||||||
Name: "File1",
|
|
||||||
Mandatory: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Target: "File3",
|
|
||||||
Name: "File3",
|
|
||||||
Mandatory: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
assert.Equal(t, publishedFiles, mP.reports)
|
|
||||||
})
|
})
|
||||||
t.Run("Nothing was downloaded", func(t *testing.T) {
|
t.Run("Nothing was downloaded", func(t *testing.T) {
|
||||||
//arrange
|
//arrange
|
||||||
build := GetMockBuildTestDownloadPublish()
|
build := GetMockBuildTestDownloadPublish()
|
||||||
mP := mockPublish{}
|
files := mock.FilesMock{}
|
||||||
//act
|
//act
|
||||||
build.PublishAllDownloadedResults("MyStep", &mP)
|
build.PublishAllDownloadedResults("MyStep", &files)
|
||||||
//assert
|
//assert
|
||||||
assert.Equal(t, 0, len(mP.reports))
|
assert.False(t, files.HasFile("/MyStep_reports.json"))
|
||||||
|
assert.False(t, files.HasFile("/MyStep_links.json"))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -408,37 +390,28 @@ func TestPublishDownloadedResults(t *testing.T) {
|
|||||||
t.Run("Publish downloaded files", func(t *testing.T) {
|
t.Run("Publish downloaded files", func(t *testing.T) {
|
||||||
//arrange
|
//arrange
|
||||||
build := GetMockBuildTestDownloadPublish()
|
build := GetMockBuildTestDownloadPublish()
|
||||||
mP := mockPublish{}
|
files := mock.FilesMock{}
|
||||||
build.Tasks[1].Results[0].SavedFilename = "SuperFile_File1"
|
build.Tasks[1].Results[0].SavedFilename = "SuperFile_File1"
|
||||||
build.Tasks[1].Results[0].DownloadPath = "Dir1/SuperFile_File1"
|
build.Tasks[1].Results[0].DownloadPath = "Dir1/SuperFile_File1"
|
||||||
build.Tasks[1].Results[2].SavedFilename = "File3"
|
build.Tasks[1].Results[2].SavedFilename = "File3"
|
||||||
build.Tasks[1].Results[2].DownloadPath = "File3"
|
build.Tasks[1].Results[2].DownloadPath = "File3"
|
||||||
//act
|
//act
|
||||||
err := build.PublishDownloadedResults("MyStep", filenames, &mP)
|
err := build.PublishDownloadedResults("MyStep", filenames, &files)
|
||||||
//assert
|
//assert
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
publishedFiles := []piperutils.Path{
|
|
||||||
{
|
assert.True(t, files.HasFile("/MyStep_reports.json"))
|
||||||
Target: "Dir1/SuperFile_File1",
|
assert.True(t, files.HasFile("/MyStep_links.json"))
|
||||||
Name: "SuperFile_File1",
|
|
||||||
Mandatory: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Target: "File3",
|
|
||||||
Name: "File3",
|
|
||||||
Mandatory: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
assert.Equal(t, publishedFiles, mP.reports)
|
|
||||||
})
|
})
|
||||||
t.Run("Try to publish file which was not downloaded", func(t *testing.T) {
|
t.Run("Try to publish file which was not downloaded", func(t *testing.T) {
|
||||||
//arrange
|
//arrange
|
||||||
build := GetMockBuildTestDownloadPublish()
|
build := GetMockBuildTestDownloadPublish()
|
||||||
mP := mockPublish{}
|
files := mock.FilesMock{}
|
||||||
build.Tasks[1].Results[0].SavedFilename = "SuperFile_File1"
|
build.Tasks[1].Results[0].SavedFilename = "SuperFile_File1"
|
||||||
build.Tasks[1].Results[0].DownloadPath = "Dir1/SuperFile_File1"
|
build.Tasks[1].Results[0].DownloadPath = "Dir1/SuperFile_File1"
|
||||||
//act
|
//act
|
||||||
err := build.PublishDownloadedResults("MyStep", filenames, &mP)
|
err := build.PublishDownloadedResults("MyStep", filenames, &files)
|
||||||
//assert
|
//assert
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -92,12 +92,22 @@ func TestCreateJSONReport(t *testing.T) {
|
|||||||
assert.Equal(t, 5, reportingData.InformationTotal)
|
assert.Equal(t, 5, reportingData.InformationTotal)
|
||||||
assert.Equal(t, 0, reportingData.InformationAudited)
|
assert.Equal(t, 0, reportingData.InformationAudited)
|
||||||
assert.Equal(t, 2, len(*reportingData.LowPerQuery))
|
assert.Equal(t, 2, len(*reportingData.LowPerQuery))
|
||||||
assert.Equal(t, "Low_Query_Name_1", (*reportingData.LowPerQuery)[0].QueryName)
|
if (*reportingData.LowPerQuery)[0].QueryName == "Low_Query_Name_1" {
|
||||||
assert.Equal(t, 0, (*reportingData.LowPerQuery)[0].Audited)
|
assert.Equal(t, "Low_Query_Name_1", (*reportingData.LowPerQuery)[0].QueryName)
|
||||||
assert.Equal(t, 4, (*reportingData.LowPerQuery)[0].Total)
|
assert.Equal(t, 0, (*reportingData.LowPerQuery)[0].Audited)
|
||||||
assert.Equal(t, "Low_Query_Name_2", (*reportingData.LowPerQuery)[1].QueryName)
|
assert.Equal(t, 4, (*reportingData.LowPerQuery)[0].Total)
|
||||||
assert.Equal(t, 5, (*reportingData.LowPerQuery)[1].Audited)
|
assert.Equal(t, "Low_Query_Name_2", (*reportingData.LowPerQuery)[1].QueryName)
|
||||||
assert.Equal(t, 5, (*reportingData.LowPerQuery)[1].Total)
|
assert.Equal(t, 5, (*reportingData.LowPerQuery)[1].Audited)
|
||||||
|
assert.Equal(t, 5, (*reportingData.LowPerQuery)[1].Total)
|
||||||
|
} else {
|
||||||
|
assert.Equal(t, "Low_Query_Name_1", (*reportingData.LowPerQuery)[1].QueryName)
|
||||||
|
assert.Equal(t, 0, (*reportingData.LowPerQuery)[1].Audited)
|
||||||
|
assert.Equal(t, 4, (*reportingData.LowPerQuery)[1].Total)
|
||||||
|
assert.Equal(t, "Low_Query_Name_2", (*reportingData.LowPerQuery)[0].QueryName)
|
||||||
|
assert.Equal(t, 5, (*reportingData.LowPerQuery)[0].Audited)
|
||||||
|
assert.Equal(t, 5, (*reportingData.LowPerQuery)[0].Total)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJsonReportWithNoLowVulnData(t *testing.T) {
|
func TestJsonReportWithNoLowVulnData(t *testing.T) {
|
||||||
|
|||||||
@@ -47,3 +47,16 @@ func (_m *HadolintPiperFileUtils) FileWrite(filename string, data []byte, perm o
|
|||||||
|
|
||||||
return r0
|
return r0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (_m *HadolintPiperFileUtils) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
|
ret := _m.Called(filename, data, perm)
|
||||||
|
|
||||||
|
var r0 error
|
||||||
|
if rf, ok := ret.Get(0).(func(string, []byte, os.FileMode) error); ok {
|
||||||
|
r0 = rf(filename, data, perm)
|
||||||
|
} else {
|
||||||
|
r0 = ret.Error(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|||||||
+15
-5
@@ -20,8 +20,8 @@ import (
|
|||||||
var dirContent []byte
|
var dirContent []byte
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultFileMode os.FileMode = 0644
|
defaultFileMode os.FileMode = 0o644
|
||||||
defaultDirMode os.FileMode = 0755
|
defaultDirMode os.FileMode = 0o755
|
||||||
)
|
)
|
||||||
|
|
||||||
type fileInfoMock struct {
|
type fileInfoMock struct {
|
||||||
@@ -50,7 +50,7 @@ func (p *fileProperties) isDir() bool {
|
|||||||
return p.content == &dirContent
|
return p.content == &dirContent
|
||||||
}
|
}
|
||||||
|
|
||||||
//FilesMock implements the functions from piperutils.Files with an in-memory file system.
|
// FilesMock implements the functions from piperutils.Files with an in-memory file system.
|
||||||
type FilesMock struct {
|
type FilesMock struct {
|
||||||
files map[string]*fileProperties
|
files map[string]*fileProperties
|
||||||
writtenFiles []string
|
writtenFiles []string
|
||||||
@@ -274,6 +274,11 @@ func (f *FilesMock) FileRead(path string) ([]byte, error) {
|
|||||||
return *props.content, nil
|
return *props.content, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadFile can be used as replacement for os.ReadFile in a compatible manner
|
||||||
|
func (f *FilesMock) ReadFile(name string) ([]byte, error) {
|
||||||
|
return f.FileRead(name)
|
||||||
|
}
|
||||||
|
|
||||||
// FileWrite just forwards to AddFile(), i.e. the content is associated with the given path.
|
// FileWrite just forwards to AddFile(), i.e. the content is associated with the given path.
|
||||||
func (f *FilesMock) FileWrite(path string, content []byte, mode os.FileMode) error {
|
func (f *FilesMock) FileWrite(path string, content []byte, mode os.FileMode) error {
|
||||||
if f.FileWriteError != nil {
|
if f.FileWriteError != nil {
|
||||||
@@ -288,6 +293,11 @@ func (f *FilesMock) FileWrite(path string, content []byte, mode os.FileMode) err
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WriteFile can be used as replacement for os.WriteFile in a compatible manner
|
||||||
|
func (f *FilesMock) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
|
return f.FileWrite(filename, data, perm)
|
||||||
|
}
|
||||||
|
|
||||||
// RemoveAll is a proxy for FileRemove
|
// RemoveAll is a proxy for FileRemove
|
||||||
func (f *FilesMock) RemoveAll(path string) error {
|
func (f *FilesMock) RemoveAll(path string) error {
|
||||||
return f.FileRemove(path)
|
return f.FileRemove(path)
|
||||||
@@ -378,7 +388,7 @@ func (f *FilesMock) TempDir(baseDir string, pattern string) (string, error) {
|
|||||||
tmpDir = fmt.Sprintf("%s/%stest", baseDir, pattern)
|
tmpDir = fmt.Sprintf("%s/%stest", baseDir, pattern)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := f.MkdirAll(tmpDir, 0755)
|
err := f.MkdirAll(tmpDir, 0o755)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
@@ -621,5 +631,5 @@ func (f *FilesMock) Open(name string) (io.ReadWriteCloser, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (f *FilesMock) Create(name string) (io.ReadWriteCloser, error) {
|
func (f *FilesMock) Create(name string) (io.ReadWriteCloser, error) {
|
||||||
return f.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
return f.OpenFile(name, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0o666)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,9 @@ type FileUtils interface {
|
|||||||
Copy(src, dest string) (int64, error)
|
Copy(src, dest string) (int64, error)
|
||||||
Move(src, dest string) error
|
Move(src, dest string) error
|
||||||
FileRead(path string) ([]byte, error)
|
FileRead(path string) ([]byte, error)
|
||||||
|
ReadFile(path string) ([]byte, error)
|
||||||
FileWrite(path string, content []byte, perm os.FileMode) error
|
FileWrite(path string, content []byte, perm os.FileMode) error
|
||||||
|
WriteFile(path string, content []byte, perm os.FileMode) error
|
||||||
FileRemove(path string) error
|
FileRemove(path string) error
|
||||||
MkdirAll(path string, perm os.FileMode) error
|
MkdirAll(path string, perm os.FileMode) error
|
||||||
Chmod(path string, mode os.FileMode) error
|
Chmod(path string, mode os.FileMode) error
|
||||||
@@ -44,15 +46,14 @@ type FileUtils interface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Files ...
|
// Files ...
|
||||||
type Files struct {
|
type Files struct{}
|
||||||
}
|
|
||||||
|
|
||||||
// TempDir creates a temporary directory
|
// TempDir creates a temporary directory
|
||||||
func (f Files) TempDir(dir, pattern string) (name string, err error) {
|
func (f Files) TempDir(dir, pattern string) (name string, err error) {
|
||||||
if len(dir) == 0 {
|
if len(dir) == 0 {
|
||||||
// lazy init system temp dir in case it doesn't exist
|
// lazy init system temp dir in case it doesn't exist
|
||||||
if exists, _ := f.DirExists(os.TempDir()); !exists {
|
if exists, _ := f.DirExists(os.TempDir()); !exists {
|
||||||
f.MkdirAll(os.TempDir(), 0666)
|
f.MkdirAll(os.TempDir(), 0o666)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,9 +95,7 @@ func (f Files) DirExists(path string) (bool, error) {
|
|||||||
|
|
||||||
// Copy ...
|
// Copy ...
|
||||||
func (f Files) Copy(src, dst string) (int64, error) {
|
func (f Files) Copy(src, dst string) (int64, error) {
|
||||||
|
|
||||||
exists, err := f.FileExists(src)
|
exists, err := f.FileExists(src)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
@@ -126,6 +125,7 @@ func (f Files) Copy(src, dst string) (int64, error) {
|
|||||||
return nBytes, err
|
return nBytes, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Move will move files from src to dst
|
||||||
func (f Files) Move(src, dst string) error {
|
func (f Files) Move(src, dst string) error {
|
||||||
if exists, err := f.FileExists(src); err != nil {
|
if exists, err := f.FileExists(src); err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -140,7 +140,7 @@ func (f Files) Move(src, dst string) error {
|
|||||||
return f.FileRemove(src)
|
return f.FileRemove(src)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Chmod is a wrapper for os.Chmod().
|
// Chmod is a wrapper for os.Chmod().
|
||||||
func (f Files) Chmod(path string, mode os.FileMode) error {
|
func (f Files) Chmod(path string, mode os.FileMode) error {
|
||||||
return os.Chmod(path, mode)
|
return os.Chmod(path, mode)
|
||||||
}
|
}
|
||||||
@@ -170,7 +170,6 @@ func (f Files) Chmod(path string, mode os.FileMode) error {
|
|||||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
// SOFTWARE.
|
// SOFTWARE.
|
||||||
func Unzip(src, dest string) ([]string, error) {
|
func Unzip(src, dest string) ([]string, error) {
|
||||||
|
|
||||||
var filenames []string
|
var filenames []string
|
||||||
|
|
||||||
r, err := zip.OpenReader(src)
|
r, err := zip.OpenReader(src)
|
||||||
@@ -236,18 +235,15 @@ func Unzip(src, dest string) ([]string, error) {
|
|||||||
// stripComponentLevel = 2 -> parentFolder/childFolder/someFile.Txt -> someFile.Txt
|
// stripComponentLevel = 2 -> parentFolder/childFolder/someFile.Txt -> someFile.Txt
|
||||||
// when stripCompenent in 0 the untar will retain the original tar folder structure
|
// when stripCompenent in 0 the untar will retain the original tar folder structure
|
||||||
// when stripCompmenet is greater than 0 the expectation is all files must be under that level folder and if not there is a hard check and failure condition
|
// when stripCompmenet is greater than 0 the expectation is all files must be under that level folder and if not there is a hard check and failure condition
|
||||||
|
|
||||||
func Untar(src string, dest string, stripComponentLevel int) error {
|
func Untar(src string, dest string, stripComponentLevel int) error {
|
||||||
file, err := os.Open(src)
|
file, err := os.Open(src)
|
||||||
defer file.Close()
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to open src: %v", err)
|
return fmt.Errorf("unable to open src: %v", err)
|
||||||
}
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
if b, err := isFileGzipped(src); err == nil && b {
|
if b, err := isFileGzipped(src); err == nil && b {
|
||||||
zr, err := gzip.NewReader(file)
|
zr, err := gzip.NewReader(file)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("requires gzip-compressed body: %v", err)
|
return fmt.Errorf("requires gzip-compressed body: %v", err)
|
||||||
}
|
}
|
||||||
@@ -301,7 +297,7 @@ func untar(r io.Reader, dir string, level int) (err error) {
|
|||||||
// write will fail with the same error.
|
// write will fail with the same error.
|
||||||
dir := filepath.Dir(abs)
|
dir := filepath.Dir(abs)
|
||||||
if !madeDir[dir] {
|
if !madeDir[dir] {
|
||||||
if err := os.MkdirAll(filepath.Dir(abs), 0755); err != nil {
|
if err := os.MkdirAll(filepath.Dir(abs), 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
madeDir[dir] = true
|
madeDir[dir] = true
|
||||||
@@ -321,7 +317,7 @@ func untar(r io.Reader, dir string, level int) (err error) {
|
|||||||
return fmt.Errorf("only wrote %d bytes to %s; expected %d", n, abs, f.Size)
|
return fmt.Errorf("only wrote %d bytes to %s; expected %d", n, abs, f.Size)
|
||||||
}
|
}
|
||||||
case mode.IsDir():
|
case mode.IsDir():
|
||||||
if err := os.MkdirAll(abs, 0755); err != nil {
|
if err := os.MkdirAll(abs, 0o755); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
madeDir[abs] = true
|
madeDir[abs] = true
|
||||||
@@ -367,14 +363,24 @@ func Copy(src, dst string) (int64, error) {
|
|||||||
return Files{}.Copy(src, dst)
|
return Files{}.Copy(src, dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileRead is a wrapper for ioutil.ReadFile().
|
// FileRead is a wrapper for os.ReadFile().
|
||||||
func (f Files) FileRead(path string) ([]byte, error) {
|
func (f Files) FileRead(path string) ([]byte, error) {
|
||||||
return ioutil.ReadFile(path)
|
return os.ReadFile(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileWrite is a wrapper for ioutil.WriteFile().
|
// ReadFile is a wrapper for os.ReadFile() using the same name and syntax.
|
||||||
|
func (f Files) ReadFile(path string) ([]byte, error) {
|
||||||
|
return f.FileRead(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
// FileWrite is a wrapper for os.WriteFile().
|
||||||
func (f Files) FileWrite(path string, content []byte, perm os.FileMode) error {
|
func (f Files) FileWrite(path string, content []byte, perm os.FileMode) error {
|
||||||
return ioutil.WriteFile(path, content, perm)
|
return os.WriteFile(path, content, perm)
|
||||||
|
}
|
||||||
|
|
||||||
|
// WriteFile is a wrapper for os.ReadFile() using the same name and syntax.
|
||||||
|
func (f Files) WriteFile(path string, content []byte, perm os.FileMode) error {
|
||||||
|
return f.FileWrite(path, content, perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FileRemove is a wrapper for os.Remove().
|
// FileRemove is a wrapper for os.Remove().
|
||||||
@@ -3,9 +3,10 @@ package piperutils
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/SAP/jenkins-library/pkg/log"
|
"github.com/SAP/jenkins-library/pkg/log"
|
||||||
"github.com/SAP/jenkins-library/pkg/piperenv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Path - struct to serialize paths and some metadata back to the invoker
|
// Path - struct to serialize paths and some metadata back to the invoker
|
||||||
@@ -16,8 +17,12 @@ type Path struct {
|
|||||||
Scope string `json:"scope"`
|
Scope string `json:"scope"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type fileWriter interface {
|
||||||
|
WriteFile(filename string, data []byte, perm os.FileMode) error
|
||||||
|
}
|
||||||
|
|
||||||
// PersistReportsAndLinks stores the report paths and links in JSON format in the workspace for processing outside
|
// PersistReportsAndLinks stores the report paths and links in JSON format in the workspace for processing outside
|
||||||
func PersistReportsAndLinks(stepName, workspace string, reports, links []Path) {
|
func PersistReportsAndLinks(stepName, workspace string, files fileWriter, reports, links []Path) error {
|
||||||
if reports == nil {
|
if reports == nil {
|
||||||
reports = []Path{}
|
reports = []Path{}
|
||||||
}
|
}
|
||||||
@@ -32,19 +37,25 @@ func PersistReportsAndLinks(stepName, workspace string, reports, links []Path) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
reportList, err := json.Marshal(&reports)
|
reportList, err := json.Marshal(&reports)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if hasMandatoryReport {
|
if hasMandatoryReport {
|
||||||
log.Entry().Fatalln("Failed to marshall reports.json data for archiving")
|
return fmt.Errorf("failed to marshall reports.json data for archiving: %w", err)
|
||||||
}
|
}
|
||||||
log.Entry().Errorln("Failed to marshall reports.json data for archiving")
|
log.Entry().Errorln("Failed to marshall reports.json data for archiving")
|
||||||
}
|
}
|
||||||
piperenv.SetParameter(workspace, fmt.Sprintf("%v_reports.json", stepName), string(reportList))
|
|
||||||
|
if err := files.WriteFile(filepath.Join(workspace, fmt.Sprintf("%v_reports.json", stepName)), reportList, 0666); err != nil {
|
||||||
|
return fmt.Errorf("failed to write reports.json: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
linkList, err := json.Marshal(&links)
|
linkList, err := json.Marshal(&links)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Entry().Errorln("Failed to marshall links.json data for archiving")
|
return fmt.Errorf("failed to marshall links.json data for archiving: %w", err)
|
||||||
} else {
|
|
||||||
piperenv.SetParameter(workspace, fmt.Sprintf("%v_links.json", stepName), string(linkList))
|
|
||||||
}
|
}
|
||||||
|
if err := files.WriteFile(filepath.Join(workspace, fmt.Sprintf("%v_links.json", stepName)), linkList, 0666); err != nil {
|
||||||
|
return fmt.Errorf("failed to write links.json: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ package piperutils
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"fmt"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@@ -10,33 +11,56 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type fileMock struct {
|
||||||
|
fileMap map[string][]byte
|
||||||
|
writeErrors map[string]error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fileMock) WriteFile(filename string, data []byte, perm os.FileMode) error {
|
||||||
|
if f.writeErrors != nil && f.writeErrors[filename] != nil {
|
||||||
|
return f.writeErrors[filename]
|
||||||
|
}
|
||||||
|
f.fileMap[filename] = data
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fileMock) ReadFile(name string) ([]byte, error) {
|
||||||
|
return f.fileMap[name], nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *fileMock) FileExists(name string) bool {
|
||||||
|
return f.fileMap[name] != nil
|
||||||
|
}
|
||||||
|
|
||||||
func TestPersistReportAndLinks(t *testing.T) {
|
func TestPersistReportAndLinks(t *testing.T) {
|
||||||
t.Run("default", func(t *testing.T) {
|
workspace := ""
|
||||||
workspace := t.TempDir()
|
t.Run("success - default", func(t *testing.T) {
|
||||||
|
files := fileMock{fileMap: map[string][]byte{}}
|
||||||
|
|
||||||
reports := []Path{{Target: "testFile1.json", Mandatory: true}, {Target: "testFile2.json"}}
|
reports := []Path{{Target: "testFile1.json", Mandatory: true}, {Target: "testFile2.json"}}
|
||||||
links := []Path{{Target: "https://1234568.com/test", Name: "Weblink"}}
|
links := []Path{{Target: "https://1234568.com/test", Name: "Weblink"}}
|
||||||
PersistReportsAndLinks("checkmarxExecuteScan", workspace, reports, links)
|
err := PersistReportsAndLinks("checkmarxExecuteScan", workspace, &files, reports, links)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
reportsJSONPath := filepath.Join(workspace, "checkmarxExecuteScan_reports.json")
|
reportsJSONPath := filepath.Join(workspace, "checkmarxExecuteScan_reports.json")
|
||||||
assert.FileExists(t, reportsJSONPath)
|
assert.True(t, files.FileExists(reportsJSONPath))
|
||||||
|
|
||||||
linksJSONPath := filepath.Join(workspace, "checkmarxExecuteScan_links.json")
|
linksJSONPath := filepath.Join(workspace, "checkmarxExecuteScan_links.json")
|
||||||
assert.FileExists(t, linksJSONPath)
|
assert.True(t, files.FileExists(linksJSONPath))
|
||||||
|
|
||||||
var reportsLoaded []Path
|
var reportsLoaded []Path
|
||||||
var linksLoaded []Path
|
var linksLoaded []Path
|
||||||
reportsFileData, err := ioutil.ReadFile(reportsJSONPath)
|
reportsFileData, err := files.ReadFile(reportsJSONPath)
|
||||||
reportsDataString := string(reportsFileData)
|
reportsDataString := string(reportsFileData)
|
||||||
println(reportsDataString)
|
println(reportsDataString)
|
||||||
assert.NoError(t, err, "No error expected but got one")
|
assert.NoError(t, err, "No error expected but got one")
|
||||||
|
|
||||||
linksFileData, err := ioutil.ReadFile(linksJSONPath)
|
linksFileData, err := files.ReadFile(linksJSONPath)
|
||||||
linksDataString := string(linksFileData)
|
linksDataString := string(linksFileData)
|
||||||
println(linksDataString)
|
println(linksDataString)
|
||||||
assert.NoError(t, err, "No error expected but got one")
|
assert.NoError(t, err, "No error expected but got one")
|
||||||
json.Unmarshal(reportsFileData, &reportsLoaded)
|
_ = json.Unmarshal(reportsFileData, &reportsLoaded)
|
||||||
json.Unmarshal(linksFileData, &linksLoaded)
|
_ = json.Unmarshal(linksFileData, &linksLoaded)
|
||||||
|
|
||||||
assert.Equal(t, 2, len(reportsLoaded), "wrong number of reports")
|
assert.Equal(t, 2, len(reportsLoaded), "wrong number of reports")
|
||||||
assert.Equal(t, 1, len(linksLoaded), "wrong number of links")
|
assert.Equal(t, 1, len(linksLoaded), "wrong number of links")
|
||||||
@@ -49,9 +73,8 @@ func TestPersistReportAndLinks(t *testing.T) {
|
|||||||
assert.Equal(t, "Weblink", linksLoaded[0].Name, "name value on link 1 has wrong value")
|
assert.Equal(t, "Weblink", linksLoaded[0].Name, "name value on link 1 has wrong value")
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("empty list", func(t *testing.T) {
|
t.Run("success - empty list", func(t *testing.T) {
|
||||||
// init
|
files := fileMock{fileMap: map[string][]byte{}}
|
||||||
workspace := t.TempDir()
|
|
||||||
|
|
||||||
reportsJSONPath := filepath.Join(workspace, "sonarExecuteScan_reports.json")
|
reportsJSONPath := filepath.Join(workspace, "sonarExecuteScan_reports.json")
|
||||||
linksJSONPath := filepath.Join(workspace, "sonarExecuteScan_links.json")
|
linksJSONPath := filepath.Join(workspace, "sonarExecuteScan_links.json")
|
||||||
@@ -62,13 +85,42 @@ func TestPersistReportAndLinks(t *testing.T) {
|
|||||||
require.Empty(t, links)
|
require.Empty(t, links)
|
||||||
|
|
||||||
// test
|
// test
|
||||||
PersistReportsAndLinks("sonarExecuteScan", workspace, reports, links)
|
err := PersistReportsAndLinks("sonarExecuteScan", workspace, &files, reports, links)
|
||||||
// assert
|
// assert
|
||||||
|
assert.NoError(t, err)
|
||||||
for _, reportFile := range []string{reportsJSONPath, linksJSONPath} {
|
for _, reportFile := range []string{reportsJSONPath, linksJSONPath} {
|
||||||
assert.FileExists(t, reportFile)
|
assert.True(t, files.FileExists(reportFile))
|
||||||
reportsFileData, err := ioutil.ReadFile(reportFile)
|
reportsFileData, err := files.ReadFile(reportFile)
|
||||||
require.NoError(t, err, "No error expected but got one")
|
require.NoError(t, err, "No error expected but got one")
|
||||||
assert.Equal(t, "[]", string(reportsFileData))
|
assert.Equal(t, "[]", string(reportsFileData))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("failure - write reports", func(t *testing.T) {
|
||||||
|
stepName := "checkmarxExecuteScan"
|
||||||
|
files := fileMock{
|
||||||
|
fileMap: map[string][]byte{},
|
||||||
|
writeErrors: map[string]error{filepath.Join(workspace, fmt.Sprintf("%v_reports.json", stepName)): fmt.Errorf("write error")},
|
||||||
|
}
|
||||||
|
|
||||||
|
reports := []Path{{Target: "testFile1.json"}, {Target: "testFile2.json"}}
|
||||||
|
links := []Path{{Target: "https://1234568.com/test", Name: "Weblink"}}
|
||||||
|
err := PersistReportsAndLinks(stepName, workspace, &files, reports, links)
|
||||||
|
|
||||||
|
assert.EqualError(t, err, "failed to write reports.json: write error")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("failure - write links", func(t *testing.T) {
|
||||||
|
stepName := "checkmarxExecuteScan"
|
||||||
|
files := fileMock{
|
||||||
|
fileMap: map[string][]byte{},
|
||||||
|
writeErrors: map[string]error{filepath.Join(workspace, fmt.Sprintf("%v_links.json", stepName)): fmt.Errorf("write error")},
|
||||||
|
}
|
||||||
|
|
||||||
|
reports := []Path{{Target: "testFile1.json"}, {Target: "testFile2.json"}}
|
||||||
|
links := []Path{{Target: "https://1234568.com/test", Name: "Weblink"}}
|
||||||
|
err := PersistReportsAndLinks(stepName, workspace, &files, reports, links)
|
||||||
|
|
||||||
|
assert.EqualError(t, err, "failed to write links.json: write error")
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"time"
|
"time"
|
||||||
@@ -31,6 +31,8 @@ type Toolrecord struct {
|
|||||||
DisplayName string
|
DisplayName string
|
||||||
DisplayURL string
|
DisplayURL string
|
||||||
|
|
||||||
|
fileUtils fileWriteUtils
|
||||||
|
|
||||||
// detailed keydata - needs tool-specific parsing
|
// detailed keydata - needs tool-specific parsing
|
||||||
Keys []keydataset
|
Keys []keydataset
|
||||||
|
|
||||||
@@ -42,9 +44,15 @@ type Toolrecord struct {
|
|||||||
reportFileName string
|
reportFileName string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type fileWriteUtils interface {
|
||||||
|
MkdirAll(path string, perm fs.FileMode) error
|
||||||
|
WriteFile(name string, data []byte, perm fs.FileMode) error
|
||||||
|
}
|
||||||
|
|
||||||
// New - initialize a new toolrecord
|
// New - initialize a new toolrecord
|
||||||
func New(workspace, toolName, toolInstance string) *Toolrecord {
|
func New(fileUtils fileWriteUtils, workspace, toolName, toolInstance string) *Toolrecord {
|
||||||
tr := Toolrecord{}
|
tr := Toolrecord{}
|
||||||
|
tr.fileUtils = fileUtils
|
||||||
|
|
||||||
tr.RecordVersion = 1
|
tr.RecordVersion = 1
|
||||||
tr.ToolName = toolName
|
tr.ToolName = toolName
|
||||||
@@ -108,7 +116,7 @@ func (tr *Toolrecord) Persist() error {
|
|||||||
}
|
}
|
||||||
// create workspace/toolrecord
|
// create workspace/toolrecord
|
||||||
dirPath := filepath.Join(tr.workspace, "toolruns")
|
dirPath := filepath.Join(tr.workspace, "toolruns")
|
||||||
err := os.MkdirAll(dirPath, os.ModePerm)
|
err := tr.fileUtils.MkdirAll(dirPath, os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("TR_PERSIST: %v", err)
|
return fmt.Errorf("TR_PERSIST: %v", err)
|
||||||
}
|
}
|
||||||
@@ -126,14 +134,14 @@ func (tr *Toolrecord) Persist() error {
|
|||||||
if len(file) == 0 {
|
if len(file) == 0 {
|
||||||
return fmt.Errorf("TR_PERSIST: empty json content")
|
return fmt.Errorf("TR_PERSIST: empty json content")
|
||||||
}
|
}
|
||||||
err = ioutil.WriteFile(tr.GetFileName(), file, 0644)
|
err = tr.fileUtils.WriteFile(tr.GetFileName(), file, 0o644)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("TR_PERSIST: %v", err)
|
return fmt.Errorf("TR_PERSIST: %v", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// default aggregation for overall displayName and URL
|
// GenerateDefaultDisplayData - default aggregation for overall displayName and URL
|
||||||
// can be overriden by calling SetOverallDisplayData
|
// can be overriden by calling SetOverallDisplayData
|
||||||
func (tr *Toolrecord) GenerateDefaultDisplayData() {
|
func (tr *Toolrecord) GenerateDefaultDisplayData() {
|
||||||
displayName := ""
|
displayName := ""
|
||||||
@@ -156,7 +164,7 @@ func (tr *Toolrecord) GenerateDefaultDisplayData() {
|
|||||||
tr.DisplayURL = displayURL
|
tr.DisplayURL = displayURL
|
||||||
}
|
}
|
||||||
|
|
||||||
// Override the default generation for DisplayName & DisplayURL
|
// SetOverallDisplayData - override the default generation for DisplayName & DisplayURL
|
||||||
func (tr *Toolrecord) SetOverallDisplayData(newName, newURL string) {
|
func (tr *Toolrecord) SetOverallDisplayData(newName, newURL string) {
|
||||||
tr.DisplayName = newName
|
tr.DisplayName = newName
|
||||||
tr.DisplayURL = newURL
|
tr.DisplayURL = newURL
|
||||||
@@ -3,6 +3,7 @@ package toolrecord_test
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/SAP/jenkins-library/pkg/mock"
|
||||||
"github.com/SAP/jenkins-library/pkg/toolrecord"
|
"github.com/SAP/jenkins-library/pkg/toolrecord"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
)
|
)
|
||||||
@@ -11,11 +12,12 @@ func TestToolRecord(t *testing.T) {
|
|||||||
workspace := t.TempDir()
|
workspace := t.TempDir()
|
||||||
|
|
||||||
t.Run("Check toolrecord", func(t *testing.T) {
|
t.Run("Check toolrecord", func(t *testing.T) {
|
||||||
tr := toolrecord.New(workspace, "dummyTool", "dummyInstance")
|
fileMock := mock.FilesMock{}
|
||||||
|
tr := toolrecord.New(&fileMock, workspace, "dummyTool", "dummyInstance")
|
||||||
|
|
||||||
tr.AddKeyData("Organization", "dummyOrgId", "dummyOrgName", "dummyOrgUrl")
|
_ = tr.AddKeyData("Organization", "dummyOrgId", "dummyOrgName", "dummyOrgUrl")
|
||||||
tr.AddKeyData("Project", "dummyProjectId", "dummyProjName", "dummyProjUrl")
|
_ = tr.AddKeyData("Project", "dummyProjectId", "dummyProjName", "dummyProjUrl")
|
||||||
tr.AddKeyData("ScanId", "dummyScanId", "dummyScanName", "dummyScanUrl")
|
_ = tr.AddKeyData("ScanId", "dummyScanId", "dummyScanName", "dummyScanUrl")
|
||||||
context := map[string]interface{}{
|
context := map[string]interface{}{
|
||||||
"demo": "data",
|
"demo": "data",
|
||||||
"anything": struct {
|
"anything": struct {
|
||||||
@@ -23,15 +25,15 @@ func TestToolRecord(t *testing.T) {
|
|||||||
i1 int
|
i1 int
|
||||||
}{"goes", 42},
|
}{"goes", 42},
|
||||||
}
|
}
|
||||||
tr.AddContext("DemoContext", context)
|
_ = tr.AddContext("DemoContext", context)
|
||||||
context2 := "a string"
|
context2 := "a string"
|
||||||
tr.AddContext("Context2", context2)
|
_ = tr.AddContext("Context2", context2)
|
||||||
var context3 [2]string
|
var context3 [2]string
|
||||||
context3[0] = "c3_1"
|
context3[0] = "c3_1"
|
||||||
context3[1] = "c3_2"
|
context3[1] = "c3_2"
|
||||||
tr.AddContext("Context3", context3)
|
_ = tr.AddContext("Context3", context3)
|
||||||
err := tr.Persist()
|
err := tr.Persist()
|
||||||
assert.Nil(t, err, "internal error %s")
|
assert.Nil(t, err, "internal error %s")
|
||||||
assert.FileExists(t, tr.GetFileName(), "toolrecord not persisted %s")
|
assert.True(t, fileMock.HasFile(tr.GetFileName()), "toolrecord not persisted %s")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user