1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2024-12-12 10:55:20 +02:00

Corr atc fail on severity (#4136)

* improved failOnSeverity Handling & Messaging

* variable correct

* Unit Test adapt

* more Unit Tests

* remove space

* function rename

* Unit Test

* stack trace like Error Output using errors.Errorf

* remove space

* remove fmt import as not used

* remove error-wrapping directive %w

* formatting directives %v for errors.Errorf

Co-authored-by: Daniel Bernd <93763187+danManSAP@users.noreply.github.com>
Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com>
This commit is contained in:
Daniel Bernd 2022-11-28 15:32:15 +01:00 committed by GitHub
parent d5562f2fb5
commit f195a94640
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 117 additions and 44 deletions

View File

@ -4,7 +4,6 @@ import (
"bytes"
"encoding/json"
"encoding/xml"
"fmt"
"io/ioutil"
"net/http"
"net/http/cookiejar"
@ -73,6 +72,7 @@ func abapEnvironmentRunATCCheck(options abapEnvironmentRunATCCheckOptions, telem
func fetchAndPersistATCResults(resp *http.Response, details abaputils.ConnectionDetailsHTTP, client piperhttp.Sender, utils piperutils.FileUtils, atcResultFileName string, generateHTML bool, failOnSeverityLevel string) error {
var err error
var failStep bool
abapEndpoint := details.URL
location := resp.Header.Get("Location")
details.URL = abapEndpoint + location
@ -88,10 +88,13 @@ func fetchAndPersistATCResults(resp *http.Response, details abaputils.Connection
}
if err == nil {
defer resp.Body.Close()
err = logAndPersistATCResult(utils, body, atcResultFileName, generateHTML, failOnSeverityLevel)
err, failStep = logAndPersistAndEvaluateATCResults(utils, body, atcResultFileName, generateHTML, failOnSeverityLevel)
}
if err != nil {
return fmt.Errorf("Handling ATC result failed: %w", err)
return errors.Errorf("Handling ATC result failed: %v", err)
}
if failStep {
return errors.Errorf("Step execution failed due to at least one ATC finding with severity equal to or higher than the failOnSeverity parameter of this step (see config.yml)")
}
return nil
}
@ -139,7 +142,7 @@ func buildATCRequestBody(config abapEnvironmentRunATCCheckOptions) (bodyString s
}
if objectSetString == "" {
return objectSetString, fmt.Errorf("Error while parsing ATC test run object set config. No object set has been provided. Please configure the objects you want to be checked for the respective test run")
return objectSetString, errors.Errorf("Error while parsing ATC test run object set config. No object set has been provided. Please configure the objects you want to be checked for the respective test run")
}
bodyString = `<?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"` + runParameters + `>` + objectSetString + `</atc:runparameters>`
@ -202,15 +205,16 @@ func getATCObjectSet(ATCConfig ATCConfiguration) (objectSet string, err error) {
return objectSet, nil
}
func logAndPersistATCResult(utils piperutils.FileUtils, body []byte, atcResultFileName string, generateHTML bool, failOnSeverityLevel string) error {
func logAndPersistAndEvaluateATCResults(utils piperutils.FileUtils, body []byte, atcResultFileName string, generateHTML bool, failOnSeverityLevel string) (error, bool) {
var failStep bool
if len(body) == 0 {
return fmt.Errorf("Parsing ATC result failed: %w", errors.New("Body is empty, can't parse empty body"))
return errors.Errorf("Parsing ATC result failed: %v", errors.New("Body is empty, can't parse empty body")), failStep
}
responseBody := string(body)
log.Entry().Debugf("Response body: %s", responseBody)
if strings.HasPrefix(responseBody, "<html>") {
return errors.New("The Software Component could not be checked. Please make sure the respective Software Component has been cloned successfully on the system")
return errors.New("The Software Component could not be checked. Please make sure the respective Software Component has been cloned successfully on the system"), failStep
}
parsedXML := new(Result)
@ -225,7 +229,6 @@ func logAndPersistATCResult(utils piperutils.FileUtils, body []byte, atcResultFi
if err == nil {
log.Entry().Infof("Writing %s file was successful", atcResultFileName)
var reports []piperutils.Path
var failStep bool
reports = append(reports, piperutils.Path{Target: atcResultFileName, Name: "ATC Results", Mandatory: true})
for _, s := range parsedXML.Files {
for _, t := range s.ATCErrors {
@ -246,14 +249,11 @@ func logAndPersistATCResult(utils piperutils.FileUtils, body []byte, atcResultFi
}
}
piperutils.PersistReportsAndLinks("abapEnvironmentRunATCCheck", "", utils, reports, nil)
if failStep {
return errors.New("Step Execution failed due to at least one ATC Finding with severity equal (or higher) to configured failOnSeverity Option - '" + failOnSeverityLevel + "'")
}
}
if err != nil {
return fmt.Errorf("Writing results failed: %w", err)
return errors.Errorf("Writing results failed: %v", err), failStep
}
return nil
return nil, failStep
}
func checkStepFailing(severity string, failOnSeverityLevel string) bool {
switch failOnSeverityLevel {
@ -307,7 +307,7 @@ func runATC(requestType string, details abaputils.ConnectionDetailsHTTP, body []
if err != nil || (resp != nil && resp.StatusCode == 400) { // send request does not seem to produce error with StatusCode 400!!!
err = abaputils.HandleHTTPError(resp, err, "triggering ATC run failed with Status: "+resp.Status, details)
log.SetErrorCategory(log.ErrorService)
return resp, fmt.Errorf("triggering ATC run failed: %w", err)
return resp, errors.Errorf("triggering ATC run failed: %v", err)
}
defer resp.Body.Close()
return resp, err
@ -337,7 +337,7 @@ func fetchXcsrfToken(requestType string, details abaputils.ConnectionDetailsHTTP
req, err := client.SendRequest(requestType, details.URL, bytes.NewBuffer(body), header, nil)
if err != nil {
log.SetErrorCategory(log.ErrorInfrastructure)
return "", fmt.Errorf("Fetching Xcsrf-Token failed: %w", err)
return "", errors.Errorf("Fetching Xcsrf-Token failed: %v", err)
}
defer req.Body.Close()
@ -351,11 +351,11 @@ func pollATCRun(details abaputils.ConnectionDetailsHTTP, body []byte, client pip
for {
resp, err := getHTTPResponseATCRun("GET", details, nil, client)
if err != nil {
return "", fmt.Errorf("Getting HTTP response failed: %w", err)
return "", errors.Errorf("Getting HTTP response failed: %v", err)
}
bodyText, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", fmt.Errorf("Reading response body failed: %w", err)
return "", errors.Errorf("Reading response body failed: %v", err)
}
x := new(Run)
@ -371,7 +371,7 @@ func pollATCRun(details abaputils.ConnectionDetailsHTTP, body []byte, client pip
return x.Link[0].Key, err
}
if x.Status == "" {
return "", fmt.Errorf("Could not get any response from ATC poll: %w", errors.New("Status from ATC run is empty. Either it's not an ABAP system or ATC run hasn't started"))
return "", errors.Errorf("Could not get any response from ATC poll: %v", errors.New("Status from ATC run is empty. Either it's not an ABAP system or ATC run hasn't started"))
}
time.Sleep(5 * time.Second)
}
@ -383,7 +383,7 @@ func getHTTPResponseATCRun(requestType string, details abaputils.ConnectionDetai
resp, err := client.SendRequest(requestType, details.URL, bytes.NewBuffer(body), header, nil)
if err != nil {
return resp, fmt.Errorf("Getting ATC run status failed: %w", err)
return resp, errors.Errorf("Getting ATC run status failed: %v", err)
}
return resp, err
}
@ -397,7 +397,7 @@ func getResultATCRun(requestType string, details abaputils.ConnectionDetailsHTTP
resp, err := client.SendRequest(requestType, details.URL, bytes.NewBuffer(body), header, nil)
if err != nil {
return resp, fmt.Errorf("Getting ATC run results failed: %w", err)
return resp, errors.Errorf("Getting ATC run results failed: %v", err)
}
return resp, err
}

View File

@ -8,7 +8,6 @@ import (
"github.com/SAP/jenkins-library/pkg/abaputils"
"github.com/SAP/jenkins-library/pkg/mock"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
)
@ -243,7 +242,8 @@ func TestParseATCResult(t *testing.T) {
</file>
</checkstyle>`
body := []byte(bodyString)
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, "")
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, "")
assert.Equal(t, false, failStep)
assert.Equal(t, nil, err)
})
t.Run("succes case: test parsing example XML result - Fail on Severity error", func(t *testing.T) {
@ -269,9 +269,11 @@ func TestParseATCResult(t *testing.T) {
</checkstyle>`
body := []byte(bodyString)
doFailOnSeverityLevel := "error"
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
expErr := errors.New("Step Execution failed due to at least one ATC Finding with severity equal (or higher) to configured failOnSeverity Option - '" + doFailOnSeverityLevel + "'")
assert.Equal(t, expErr.Error(), err.Error())
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
//fail true
assert.Equal(t, true, failStep)
//but no error here
assert.Equal(t, nil, err)
})
t.Run("succes case: test parsing example XML result - Fail on Severity warning", func(t *testing.T) {
dir := t.TempDir()
@ -296,9 +298,11 @@ func TestParseATCResult(t *testing.T) {
</checkstyle>`
body := []byte(bodyString)
doFailOnSeverityLevel := "warning"
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
expErr := errors.New("Step Execution failed due to at least one ATC Finding with severity equal (or higher) to configured failOnSeverity Option - '" + doFailOnSeverityLevel + "'")
assert.Equal(t, expErr.Error(), err.Error())
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
//fail true
assert.Equal(t, true, failStep)
//but no error here
assert.Equal(t, nil, err)
})
t.Run("succes case: test parsing example XML result - Fail on Severity info", func(t *testing.T) {
dir := t.TempDir()
@ -323,9 +327,11 @@ func TestParseATCResult(t *testing.T) {
</checkstyle>`
body := []byte(bodyString)
doFailOnSeverityLevel := "info"
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
expErr := errors.New("Step Execution failed due to at least one ATC Finding with severity equal (or higher) to configured failOnSeverity Option - '" + doFailOnSeverityLevel + "'")
assert.Equal(t, expErr.Error(), err.Error())
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
//fail true
assert.Equal(t, true, failStep)
//but no error here
assert.Equal(t, nil, err)
})
t.Run("succes case: test parsing example XML result - Fail on Severity warning - only errors", func(t *testing.T) {
dir := t.TempDir()
@ -350,9 +356,11 @@ func TestParseATCResult(t *testing.T) {
</checkstyle>`
body := []byte(bodyString)
doFailOnSeverityLevel := "warning"
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
expErr := errors.New("Step Execution failed due to at least one ATC Finding with severity equal (or higher) to configured failOnSeverity Option - '" + doFailOnSeverityLevel + "'")
assert.Equal(t, expErr.Error(), err.Error())
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
//fail true
assert.Equal(t, true, failStep)
//but no error here
assert.Equal(t, nil, err)
})
t.Run("succes case: test parsing example XML result - Fail on Severity info - only errors", func(t *testing.T) {
dir := t.TempDir()
@ -377,11 +385,13 @@ func TestParseATCResult(t *testing.T) {
</checkstyle>`
body := []byte(bodyString)
doFailOnSeverityLevel := "info"
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
expErr := errors.New("Step Execution failed due to at least one ATC Finding with severity equal (or higher) to configured failOnSeverity Option - '" + doFailOnSeverityLevel + "'")
assert.Equal(t, expErr.Error(), err.Error())
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
//fail true
assert.Equal(t, true, failStep)
//but no error here
assert.Equal(t, nil, err)
})
t.Run("succes case: test parsing example XML result - Fail on Severity warning - only warnings", func(t *testing.T) {
t.Run("succes case: test parsing example XML result - Fail on Severity info - only warnings", func(t *testing.T) {
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
@ -404,9 +414,69 @@ func TestParseATCResult(t *testing.T) {
</checkstyle>`
body := []byte(bodyString)
doFailOnSeverityLevel := "info"
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
expErr := errors.New("Step Execution failed due to at least one ATC Finding with severity equal (or higher) to configured failOnSeverity Option - '" + doFailOnSeverityLevel + "'")
assert.Equal(t, expErr.Error(), err.Error())
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
//fail true
assert.Equal(t, true, failStep)
//but no error here
assert.Equal(t, nil, err)
})
t.Run("succes case: test parsing example XML result - NOT Fail on Severity warning - only infos", func(t *testing.T) {
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `<?xml version="1.0" encoding="UTF-8"?>
<checkstyle>
<file name="testFile">
<error message="testMessage1" source="sourceTester" line="1" severity="info">
</error>
<error message="testMessage2" source="sourceTester" line="2" severity="info">
</error>
</file>
<file name="testFile2">
<error message="testMessage" source="sourceTester" line="1" severity="info">
</error>
</file>
</checkstyle>`
body := []byte(bodyString)
doFailOnSeverityLevel := "warning"
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
//fail false
assert.Equal(t, false, failStep)
//no error here
assert.Equal(t, nil, err)
})
t.Run("succes case: test parsing example XML result - NOT Fail on Severity error - only warnings", func(t *testing.T) {
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `<?xml version="1.0" encoding="UTF-8"?>
<checkstyle>
<file name="testFile">
<error message="testMessage1" source="sourceTester" line="1" severity="warning">
</error>
<error message="testMessage2" source="sourceTester" line="2" severity="warning">
</error>
</file>
<file name="testFile2">
<error message="testMessage" source="sourceTester" line="1" severity="warning">
</error>
</file>
</checkstyle>`
body := []byte(bodyString)
doFailOnSeverityLevel := "error"
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, doFailOnSeverityLevel)
//fail false
assert.Equal(t, false, failStep)
//no error here
assert.Equal(t, nil, err)
})
t.Run("succes case: test parsing empty XML result", func(t *testing.T) {
dir := t.TempDir()
@ -420,14 +490,16 @@ func TestParseATCResult(t *testing.T) {
<checkstyle>
</checkstyle>`
body := []byte(bodyString)
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, "")
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, "")
assert.Equal(t, false, failStep)
assert.Equal(t, nil, err)
})
t.Run("failure case: parsing empty xml", func(t *testing.T) {
var bodyString string
body := []byte(bodyString)
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, "")
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, "")
assert.Equal(t, false, failStep)
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) {
@ -440,7 +512,8 @@ func TestParseATCResult(t *testing.T) {
}()
bodyString := `<html><head><title>HTMLTestResponse</title</head></html>`
body := []byte(bodyString)
err := logAndPersistATCResult(&mock.FilesMock{}, body, "ATCResults.xml", false, "")
err, failStep := logAndPersistAndEvaluateATCResults(&mock.FilesMock{}, body, "ATCResults.xml", false, "")
assert.Equal(t, false, failStep)
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")
})
}