//go:build unit
// +build unit
package cmd
import (
"encoding/xml"
"os"
"testing"
"github.com/SAP/jenkins-library/pkg/abaputils"
"github.com/SAP/jenkins-library/pkg/mock"
"github.com/stretchr/testify/assert"
)
func TestHostConfig(t *testing.T) {
t.Run("Check Host: ABAP Endpoint", func(t *testing.T) {
config := abaputils.AbapEnvironmentOptions{
Username: "testUser",
Password: "testPassword",
Host: "https://api.endpoint.com",
}
options := abaputils.AbapEnvironmentRunATCCheckOptions{
AbapEnvOptions: config,
}
execRunner := &mock.ExecMockRunner{}
autils := abaputils.AbapUtils{
Exec: execRunner,
}
var con abaputils.ConnectionDetailsHTTP
con, error := autils.GetAbapCommunicationArrangementInfo(options.AbapEnvOptions, "")
if error == nil {
assert.Equal(t, "testUser", con.User)
assert.Equal(t, "testPassword", con.Password)
assert.Equal(t, "https://api.endpoint.com", con.URL)
assert.Equal(t, "", con.XCsrfToken)
}
})
t.Run("No host/ServiceKey configuration", func(t *testing.T) {
// Testing without CfOrg parameter
config := abaputils.AbapEnvironmentOptions{
CfAPIEndpoint: "https://api.endpoint.com",
CfSpace: "testSpace",
CfServiceInstance: "testInstance",
CfServiceKeyName: "testServiceKey",
Username: "testUser",
Password: "testPassword",
}
options := abaputils.AbapEnvironmentRunATCCheckOptions{
AbapEnvOptions: config,
}
execRunner := &mock.ExecMockRunner{}
autils := abaputils.AbapUtils{
Exec: execRunner,
}
_, err := autils.GetAbapCommunicationArrangementInfo(options.AbapEnvOptions, "")
assert.EqualError(t, err, "Parameters missing. Please provide EITHER the Host of the ABAP server OR the Cloud Foundry ApiEndpoint, Organization, Space, Service Instance and a corresponding Service Key for the Communication Scenario SAP_COM_0510")
_, err = autils.GetAbapCommunicationArrangementInfo(options.AbapEnvOptions, "")
assert.EqualError(t, err, "Parameters missing. Please provide EITHER the Host of the ABAP server OR the Cloud Foundry ApiEndpoint, Organization, Space, Service Instance and a corresponding Service Key for the Communication Scenario SAP_COM_0510")
})
t.Run("Check Host: CF Service Key", func(t *testing.T) {
config := abaputils.AbapEnvironmentOptions{
CfAPIEndpoint: "https://api.endpoint.com",
CfSpace: "testSpace",
CfOrg: "Test",
CfServiceInstance: "testInstance",
CfServiceKeyName: "testServiceKey",
Username: "testUser",
Password: "testPassword",
}
options := abaputils.AbapEnvironmentRunATCCheckOptions{
AbapEnvOptions: config,
}
execRunner := &mock.ExecMockRunner{}
autils := abaputils.AbapUtils{
Exec: execRunner,
}
var con abaputils.ConnectionDetailsHTTP
con, error := autils.GetAbapCommunicationArrangementInfo(options.AbapEnvOptions, "")
if error == nil {
assert.Equal(t, "", con.User)
assert.Equal(t, "", con.Password)
assert.Equal(t, "", con.URL)
assert.Equal(t, "", con.XCsrfToken)
}
})
}
func TestATCTrigger(t *testing.T) {
t.Run("Trigger ATC run test", func(t *testing.T) {
tokenExpected := "myToken"
client := &abaputils.ClientMock{
Body: `ATC trigger test`,
Token: tokenExpected,
}
con := abaputils.ConnectionDetailsHTTP{
User: "Test",
Password: "Test",
URL: "https://api.endpoint.com/Entity/",
}
resp, error := runATC("GET", con, []byte(client.Body), client)
if error == nil {
assert.Equal(t, tokenExpected, resp.Header["X-Csrf-Token"][0])
assert.Equal(t, int64(0), resp.ContentLength)
assert.Equal(t, []string([]string(nil)), resp.Header["Location"])
}
})
}
func TestFetchXcsrfToken(t *testing.T) {
t.Run("FetchXcsrfToken Test", func(t *testing.T) {
tokenExpected := "myToken"
client := &abaputils.ClientMock{
Body: `Xcsrf Token test`,
Token: tokenExpected,
}
con := abaputils.ConnectionDetailsHTTP{
User: "Test",
Password: "Test",
URL: "https://api.endpoint.com/Entity/",
}
token, error := fetchXcsrfToken("GET", con, []byte(client.Body), client)
if error == nil {
assert.Equal(t, tokenExpected, token)
}
})
t.Run("failure case: fetch token", func(t *testing.T) {
tokenExpected := ""
client := &abaputils.ClientMock{
Body: `Xcsrf Token test`,
Token: "",
}
con := abaputils.ConnectionDetailsHTTP{
User: "Test",
Password: "Test",
URL: "https://api.endpoint.com/Entity/",
}
token, error := fetchXcsrfToken("GET", con, []byte(client.Body), client)
if error == nil {
assert.Equal(t, tokenExpected, token)
}
})
}
func TestPollATCRun(t *testing.T) {
t.Run("ATC run Poll Test", func(t *testing.T) {
tokenExpected := "myToken"
client := &abaputils.ClientMock{
Body: `ATC Poll test`,
Token: tokenExpected,
}
con := abaputils.ConnectionDetailsHTTP{
User: "Test",
Password: "Test",
URL: "https://api.endpoint.com/Entity/",
}
resp, err := pollATCRun(con, []byte(client.Body), client)
if err != nil {
assert.Equal(t, "", resp)
assert.EqualError(t, err, "Could not get any response from ATC poll: Status from ATC run is empty. Either it's not an ABAP system or ATC run hasn't started")
}
})
}
func TestGetHTTPResponseATCRun(t *testing.T) {
t.Run("Get HTTP Response from ATC run Test", func(t *testing.T) {
client := &abaputils.ClientMock{
Body: `HTTP response test`,
}
con := abaputils.ConnectionDetailsHTTP{
User: "Test",
Password: "Test",
URL: "https://api.endpoint.com/Entity/",
}
resp, err := getHTTPResponseATCRun("GET", con, []byte(client.Body), client)
assert.NoError(t, err)
defer resp.Body.Close()
if err == nil {
assert.Equal(t, int64(0), resp.ContentLength)
assert.Equal(t, []string([]string(nil)), resp.Header["X-Crsf-Token"])
}
})
}
func TestGetResultATCRun(t *testing.T) {
t.Run("Get HTTP Response from ATC run Test", func(t *testing.T) {
client := &abaputils.ClientMock{
BodyList: []string{
`ATC result body`,
},
}
con := abaputils.ConnectionDetailsHTTP{
User: "Test",
Password: "Test",
URL: "https://api.endpoint.com/Entity/",
}
resp, err := getResultATCRun("GET", con, []byte(client.Body), client)
assert.NoError(t, err)
defer resp.Body.Close()
if err == nil {
assert.Equal(t, int64(0), resp.ContentLength)
assert.Equal(t, []string([]string(nil)), resp.Header["X-Crsf-Token"])
}
})
}
func TestParseATCResult(t *testing.T) {
t.Run("succes case: test parsing example XML result", func(t *testing.T) {
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `
`
body := []byte(bodyString)
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) {
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `
`
body := []byte(bodyString)
doFailOnSeverityLevel := "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()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `
`
body := []byte(bodyString)
doFailOnSeverityLevel := "warning"
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()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `
`
body := []byte(bodyString)
doFailOnSeverityLevel := "info"
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()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `
`
body := []byte(bodyString)
doFailOnSeverityLevel := "warning"
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()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `
`
body := []byte(bodyString)
doFailOnSeverityLevel := "info"
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 warnings", func(t *testing.T) {
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `
`
body := []byte(bodyString)
doFailOnSeverityLevel := "info"
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 := `
`
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 := `
`
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()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `
`
body := []byte(bodyString)
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, 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) {
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
bodyString := `
HTMLTestResponse`
body := []byte(bodyString)
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")
})
}
func TestBuildATCCheckBody(t *testing.T) {
t.Run("Test build body with no ATC Object set - no software component and package", func(t *testing.T) {
expectedObjectSet := ""
var config ATCConfiguration
objectSet, err := getATCObjectSet(config)
assert.Equal(t, expectedObjectSet, objectSet)
assert.Equal(t, nil, err)
})
t.Run("success case: Test build body with example yaml config", func(t *testing.T) {
expectedObjectSet := ""
config := ATCConfiguration{
"",
"",
ATCObjects{
Package: []Package{
{Name: "testPackage", IncludeSubpackages: true},
{Name: "testPackage2", IncludeSubpackages: false},
},
SoftwareComponent: []SoftwareComponent{
{Name: "testSoftwareComponent"},
{Name: "testSoftwareComponent2"},
},
},
abaputils.ObjectSet{},
}
objectSet, err := getATCObjectSet(config)
assert.Equal(t, expectedObjectSet, objectSet)
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) {
expectedObjectSet := ``
var err error
config := ATCConfiguration{
"",
"",
ATCObjects{
Package: []Package{
{Name: "testPackage", IncludeSubpackages: true},
{Name: "testPackage2", IncludeSubpackages: false},
},
},
abaputils.ObjectSet{},
}
objectSet, err := getATCObjectSet(config)
assert.Equal(t, expectedObjectSet, objectSet)
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) {
expectedObjectSet := ``
config := ATCConfiguration{
"",
"",
ATCObjects{
SoftwareComponent: []SoftwareComponent{
{Name: "testSoftwareComponent"},
{Name: "testSoftwareComponent2"},
},
},
abaputils.ObjectSet{},
}
objectSet, err := getATCObjectSet(config)
assert.Equal(t, expectedObjectSet, objectSet)
assert.Equal(t, nil, err)
})
}
func TestGenerateHTMLDocument(t *testing.T) {
// 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) {
expectedResult := "ATC ResultsATC Results
Severity | File | Message | Line | Checked by |
---|
error | testFile2 | testMessage | 1 | sourceTester |
warning | testFile | testMessage2 | 2 | sourceTester |
info | testFile | testMessage1 | 1 | sourceTester |
"
bodyString := `
`
parsedXML := new(Result)
err := xml.Unmarshal([]byte(bodyString), &parsedXML)
if assert.NoError(t, err) {
htmlDocumentResult := generateHTMLDocument(parsedXML)
assert.Equal(t, expectedResult, htmlDocumentResult)
}
})
}
func TestResolveConfiguration(t *testing.T) {
t.Run("resolve atcConfig-yml with ATC Set", func(t *testing.T) {
expectedBodyString := ""
config := abapEnvironmentRunATCCheckOptions{
AtcConfig: "atc.yml",
}
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
yamlBody := `checkvariant: MY_TEST
configuration: MY_CONFIG
atcobjects:
package:
- name: Z_TEST
- name: Z_TEST_TREE
includesubpackage: true
softwarecomponent:
- name: Z_TEST
- name: /DMO/SWC
`
err := os.WriteFile(config.AtcConfig, []byte(yamlBody), 0o644)
if assert.Equal(t, err, nil) {
bodyString, err := buildATCRequestBody(config)
assert.Equal(t, nil, err)
assert.Equal(t, expectedBodyString, bodyString)
}
})
t.Run("resolve atcConfig-yml with OSL", func(t *testing.T) {
config := abapEnvironmentRunATCCheckOptions{
AtcConfig: "atc.yml",
}
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
yamlBody := `checkvariant: MY_TEST
configuration: MY_CONFIG
objectset:
type: multiPropertySet
multipropertyset:
packages:
- name: Z_TEST
packagetrees:
- name: Z_TEST_TREE
softwarecomponents:
- name: Z_TEST
- name: /DMO/SWC
`
expectedBodyString := ""
err := os.WriteFile(config.AtcConfig, []byte(yamlBody), 0o644)
if assert.Equal(t, err, nil) {
bodyString, err := buildATCRequestBody(config)
assert.Equal(t, nil, err)
assert.Equal(t, expectedBodyString, bodyString)
}
})
t.Run("resolve repo-yml", func(t *testing.T) {
expectedBodyString := ""
config := abapEnvironmentRunATCCheckOptions{
Repositories: "repo.yml",
}
dir := t.TempDir()
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
}()
yamlBody := `repositories:
- name: Z_TEST
- name: /DMO/SWC
`
err := os.WriteFile(config.Repositories, []byte(yamlBody), 0o644)
if assert.Equal(t, err, nil) {
bodyString, err := buildATCRequestBody(config)
assert.Equal(t, nil, err)
assert.Equal(t, expectedBodyString, bodyString)
}
})
t.Run("Missing config files", func(t *testing.T) {
config := abapEnvironmentRunATCCheckOptions{
AtcConfig: "atc.yml",
}
bodyString, err := buildATCRequestBody(config)
assert.Equal(t, "Could not find atc.yml", err.Error())
assert.Equal(t, "", bodyString)
})
t.Run("Config file not specified", func(t *testing.T) {
config := abapEnvironmentRunATCCheckOptions{}
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, "", bodyString)
})
}