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

Feature: ATC & AUNIT - ObjectSetLibrary(OSL) usage (#3755)

* own OSL go File & first changes ATC step

* OSL Integration in AUnit & ATC steps 1

* OSL & Unit Tests

* Unit Tests 1

* OSL - AUnit & ATC usage

* Unittest ATC: packagetree --> package incl. subpackages

* correct spelling

* yaml & generated update

* generated Metadata

Co-authored-by: Daniel Bernd <93763187+danManSAP@users.noreply.github.com>
This commit is contained in:
Daniel Bernd 2022-04-27 13:30:43 +02:00 committed by GitHub
parent 9d8f3fc6ad
commit a3f1234a60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 331 additions and 273 deletions

16
.gitignore vendored
View File

@ -46,3 +46,19 @@ ATCResults.xml
AUnitResults.xml
ATCResults.html
AUnitResults.html
<<<<<<< HEAD
/cmd/*
=======
/cmd/temp-*
/cmd/toolruns
/cmd/checkmarx
/cmd/.pipeline
/cmd/fortify
/cmd/protecode
cmd/dockerimagename_latest.tar
<<<<<<< HEAD
>>>>>>> 06e5ca29 (OSL - AUnit & ATC usage)
=======
cmd/atcSystemConfig.json
>>>>>>> b126ba70 (Unittest ATC: packagetree --> package incl. subpackages)

View File

@ -8,6 +8,7 @@ import (
"io/ioutil"
"net/http"
"net/http/cookiejar"
"reflect"
"strconv"
"strings"
"time"
@ -131,16 +132,28 @@ func buildATCRequestBody(config abapEnvironmentRunATCCheckOptions) (bodyString s
runParameters += ` configuration="` + atcConfig.Configuration + `"`
}
objectSet, err := getATCObjectSet(atcConfig)
var objectSetString string
//check if OSL Objectset is present
if !reflect.DeepEqual(abaputils.ObjectSet{}, atcConfig.ObjectSet) {
objectSetString = abaputils.BuildOSLString(atcConfig.ObjectSet)
}
//if initial - check if ATC Object set is present
if objectSetString == "" && (len(atcConfig.Objects.Package) != 0 || len(atcConfig.Objects.SoftwareComponent) != 0) {
objectSetString, err = getATCObjectSet(atcConfig)
}
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 + `>` + objectSet + `</atc:runparameters>`
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")
}
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>`
return bodyString, err
}
func resolveATCConfiguration(config abapEnvironmentRunATCCheckOptions) (atcConfig ATCConfiguration, err error) {
if config.AtcConfig != "" {
// Configuration defaults to AUnitConfig
// Configuration defaults to ATC Config
log.Entry().Infof("ATC Configuration: %s", config.AtcConfig)
atcConfigFile, err := abaputils.ReadConfigFile(config.AtcConfig)
if err != nil {
@ -167,11 +180,6 @@ func resolveATCConfiguration(config abapEnvironmentRunATCCheckOptions) (atcConfi
}
func getATCObjectSet(ATCConfig ATCConfiguration) (objectSet string, err error) {
if len(ATCConfig.Objects.Package) == 0 && len(ATCConfig.Objects.SoftwareComponent) == 0 {
log.SetErrorCategory(log.ErrorConfiguration)
return "", fmt.Errorf("Error while parsing ATC run config. Please provide the packages and/or the software components to be checked! %w", errors.New("No Package or Software Component specified. Please provide either one or both of them"))
}
objectSet += `<obj:objectSet>`
//Build SC XML body
@ -240,6 +248,7 @@ func logAndPersistATCResult(body []byte, atcResultFileName string, generateHTML
return fmt.Errorf("Writing results failed: %w", err)
}
return nil
}
func runATC(requestType string, details abaputils.ConnectionDetailsHTTP, body []byte, client piperhttp.Sender) (*http.Response, error) {
@ -292,6 +301,7 @@ func fetchXcsrfToken(requestType string, details abaputils.ConnectionDetailsHTTP
token := req.Header.Get("X-Csrf-Token")
return token, err
}
func pollATCRun(details abaputils.ConnectionDetailsHTTP, body []byte, client piperhttp.Sender) (string, error) {
@ -398,9 +408,10 @@ func generateHTMLDocument(parsedXML *Result) (htmlDocumentString string) {
//ATCConfiguration object for parsing yaml config of software components and packages
type ATCConfiguration struct {
CheckVariant string `json:"checkvariant,omitempty"`
Configuration string `json:"configuration,omitempty"`
Objects ATCObjects `json:"atcobjects"`
CheckVariant string `json:"checkvariant,omitempty"`
Configuration string `json:"configuration,omitempty"`
Objects ATCObjects `json:"atcobjects"`
ObjectSet abaputils.ObjectSet `json:"objectset,omitempty"`
}
//ATCObjects in form of packages and software components to be checked

View File

@ -51,7 +51,7 @@ Please provide either of the following options:
* The Cloud Foundry parameters (API endpoint, organization, space), credentials, the service instance for the ABAP service and the service key for the Communication Scenario SAP_COM_0510.
* Only provide one of those options with the respective credentials. If all values are provided, the direct communication (via host) has priority.
Regardless of the option you chose, please make sure to provide the configuration for Software Components and Packages that you want to be checked analog to the examples listed on this page.`,
Regardless of the option you chose, please make sure to provide the configuration the object set (e.g. with Software Components and Packages) that you want to be checked analog to the examples listed on this page.`,
PreRunE: func(cmd *cobra.Command, _ []string) error {
startTime = time.Now()
log.SetStepName(STEP_NAME)
@ -128,7 +128,7 @@ Regardless of the option you chose, please make sure to provide the configuratio
}
func addAbapEnvironmentRunATCCheckFlags(cmd *cobra.Command, stepConfig *abapEnvironmentRunATCCheckOptions) {
cmd.Flags().StringVar(&stepConfig.AtcConfig, "atcConfig", os.Getenv("PIPER_atcConfig"), "Path to a YAML configuration file for Packages and/or Software Components to be checked during ATC run")
cmd.Flags().StringVar(&stepConfig.AtcConfig, "atcConfig", os.Getenv("PIPER_atcConfig"), "Path to a YAML configuration file for the object set to be checked during ATC run")
cmd.Flags().StringVar(&stepConfig.Repositories, "repositories", os.Getenv("PIPER_repositories"), "Specifies a YAML file containing the repositories configuration")
cmd.Flags().StringVar(&stepConfig.CfAPIEndpoint, "cfApiEndpoint", os.Getenv("PIPER_cfApiEndpoint"), "Cloud Foundry API endpoint")
cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "CF org")

View File

@ -297,15 +297,15 @@ func TestParseATCResult(t *testing.T) {
}
func TestBuildATCCheckBody(t *testing.T) {
t.Run("Test build body with no software component and package", func(t *testing.T) {
expectedObjectSet := ""
t.Run("Test build body with no ATC Object set - no software component and package", func(t *testing.T) {
expectedObjectSet := "<obj:objectSet></obj:objectSet>"
var config ATCConfiguration
objectSet, err := getATCObjectSet(config)
assert.Equal(t, expectedObjectSet, objectSet)
assert.EqualError(t, err, "Error while parsing ATC run config. Please provide the packages and/or the software components to be checked! No Package or Software Component specified. Please provide either one or both of them")
assert.Equal(t, nil, err)
})
t.Run("success case: Test build body with example yaml config", func(t *testing.T) {
@ -324,6 +324,7 @@ func TestBuildATCCheckBody(t *testing.T) {
{Name: "testSoftwareComponent2"},
},
},
abaputils.ObjectSet{},
}
objectSet, err := getATCObjectSet(config)
@ -336,9 +337,8 @@ func TestBuildATCCheckBody(t *testing.T) {
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 config ATCConfiguration
config = ATCConfiguration{
config := ATCConfiguration{
"",
"",
ATCObjects{
@ -347,13 +347,13 @@ func TestBuildATCCheckBody(t *testing.T) {
{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) {
@ -368,6 +368,7 @@ func TestBuildATCCheckBody(t *testing.T) {
{Name: "testSoftwareComponent2"},
},
},
abaputils.ObjectSet{},
}
objectSet, err := getATCObjectSet(config)
@ -407,9 +408,9 @@ func TestGenerateHTMLDocument(t *testing.T) {
func TestResolveConfiguration(t *testing.T) {
t.Run("resolve atcConfig-yml", 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: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{
AtcConfig: "atc.yml",
}
@ -431,6 +432,8 @@ configuration: MY_CONFIG
atcobjects:
package:
- name: Z_TEST
- name: Z_TEST_TREE
includesubpackage: true
softwarecomponent:
- name: Z_TEST
- name: /DMO/SWC
@ -445,6 +448,47 @@ atcobjects:
})
t.Run("resolve atcConfig-yml with OSL", func(t *testing.T) {
config := abapEnvironmentRunATCCheckOptions{
AtcConfig: "atc.yml",
}
dir, err := ioutil.TempDir("", "atcDir")
if err != nil {
t.Fatal("Failed to create temporary directory")
}
oldCWD, _ := os.Getwd()
_ = os.Chdir(dir)
// clean up tmp dir
defer func() {
_ = os.Chdir(oldCWD)
_ = os.RemoveAll(dir)
}()
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 := "<?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)
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 := "<?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>"

View File

@ -21,38 +21,6 @@ import (
"github.com/pkg/errors"
)
type abapEnvironmentRunAUnitTestUtils interface {
command.ExecRunner
FileExists(filename string) (bool, error)
// Add more methods here, or embed additional interfaces, or remove/replace as required.
// The abapEnvironmentRunAUnitTestUtils interface should be descriptive of your runtime dependencies,
// i.e. include everything you need to be able to mock in tests.
// Unit tests shall be executable in parallel (not depend on global state), and don't (re-)test dependencies.
}
type abapEnvironmentRunAUnitTestUtilsBundle struct {
*command.Command
*piperutils.Files
// Embed more structs as necessary to implement methods or interfaces you add to abapEnvironmentRunAUnitTestUtils.
// Structs embedded in this way must each have a unique set of methods attached.
// If there is no struct which implements the method you need, attach the method to
// abapEnvironmentRunAUnitTestUtilsBundle and forward to the implementation of the dependency.
}
func newAbapEnvironmentRunAUnitTestUtils() abapEnvironmentRunAUnitTestUtils {
utils := abapEnvironmentRunAUnitTestUtilsBundle{
Command: &command.Command{},
Files: &piperutils.Files{},
}
// Reroute command output to logging framework
utils.Stdout(log.Writer())
utils.Stderr(log.Writer())
return &utils
}
func abapEnvironmentRunAUnitTest(config abapEnvironmentRunAUnitTestOptions, telemetryData *telemetry.CustomData) {
// for command execution use Command
@ -141,7 +109,7 @@ func resolveAUnitConfiguration(config abapEnvironmentRunAUnitTestOptions) (aUnit
return aUnitConfig, err
}
for _, repo := range repos {
aUnitConfig.ObjectSet.SoftwareComponents = append(aUnitConfig.ObjectSet.SoftwareComponents, SoftwareComponents{Name: repo.Name})
aUnitConfig.ObjectSet.SoftwareComponents = append(aUnitConfig.ObjectSet.SoftwareComponents, abaputils.SoftwareComponents{Name: repo.Name})
}
aUnitConfig.Title = "AUnit Test Run"
return aUnitConfig, nil
@ -207,7 +175,7 @@ func buildAUnitRequestBody(config abapEnvironmentRunAUnitTestOptions) (bodyStrin
if AUnitConfig.Context == "" {
AUnitConfig.Context = "ABAP Environment Pipeline"
}
if reflect.DeepEqual(ObjectSet{}, AUnitConfig.ObjectSet) {
if reflect.DeepEqual(abaputils.ObjectSet{}, AUnitConfig.ObjectSet) {
return bodyString, fmt.Errorf("Error while parsing AUnit 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")
}
@ -216,7 +184,7 @@ func buildAUnitRequestBody(config abapEnvironmentRunAUnitTestOptions) (bodyStrin
//Build metadata string
metadataString := `<aunit:run title="` + AUnitConfig.Title + `" context="` + AUnitConfig.Context + `" xmlns:aunit="http://www.sap.com/adt/api/aunit">`
//Build Object Set
objectSetString := buildAUnitObjectSetString(AUnitConfig)
objectSetString := abaputils.BuildOSLString(AUnitConfig.ObjectSet)
bodyString += `<?xml version="1.0" encoding="UTF-8"?>` + metadataString + optionsString + objectSetString + `</aunit:run>`
@ -297,78 +265,6 @@ func buildAUnitOptionsString(AUnitConfig AUnitConfig) (optionsString string) {
return optionsString
}
func writeObjectSetProperties(set MultiPropertySet) (objectSetString string) {
for _, packages := range set.PackageNames {
objectSetString += `<osl:package name="` + packages.Name + `"/>`
}
for _, objectTypeGroup := range set.ObjectTypeGroups {
objectSetString += `<osl:objectTypeGroup name="` + objectTypeGroup.Name + `"/>`
}
for _, objectType := range set.ObjectTypes {
objectSetString += `<osl:objectType name="` + objectType.Name + `"/>`
}
for _, owner := range set.Owners {
objectSetString += `<osl:owner name="` + owner.Name + `"/>`
}
for _, releaseState := range set.ReleaseStates {
objectSetString += `<osl:releaseState value="` + releaseState.Value + `"/>`
}
for _, version := range set.Versions {
objectSetString += `<osl:version value="` + version.Value + `"/>`
}
for _, applicationComponent := range set.ApplicationComponents {
objectSetString += `<osl:applicationComponent name="` + applicationComponent.Name + `"/>`
}
for _, component := range set.SoftwareComponents {
objectSetString += `<osl:softwareComponent name="` + component.Name + `"/>`
}
for _, transportLayer := range set.TransportLayers {
objectSetString += `<osl:transportLayer name="` + transportLayer.Name + `"/>`
}
for _, language := range set.Languages {
objectSetString += `<osl:language value="` + language.Value + `"/>`
}
for _, sourceSystem := range set.SourceSystems {
objectSetString += `<osl:sourceSystem name="` + sourceSystem.Name + `"/>`
}
return objectSetString
}
func buildAUnitObjectSetString(AUnitConfig AUnitConfig) (objectSetString string) {
//Build ObjectSets
s := AUnitConfig.ObjectSet
if s.Type == "" {
s.Type = "multiPropertySet"
}
if s.Type != "multiPropertySet" {
log.Entry().Infof("Wrong configuration has been detected: %s has been used. This is currently not supported and this set will not be included in this run. Please check the step documentation for more information", s.Type)
} else {
objectSetString += `<osl:objectSet xsi:type="` + s.Type + `" xmlns:osl="http://www.sap.com/api/osl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">`
if !(reflect.DeepEqual(s.PackageNames, AUnitPackage{})) || !(reflect.DeepEqual(s.SoftwareComponents, SoftwareComponents{})) {
//To ensure Scomps and packages can be assigned on this level
mps := MultiPropertySet{
PackageNames: s.PackageNames,
SoftwareComponents: s.SoftwareComponents,
}
objectSetString += writeObjectSetProperties(mps)
}
objectSetString += writeObjectSetProperties(s.MultiPropertySet)
if !(reflect.DeepEqual(s.MultiPropertySet, MultiPropertySet{})) {
log.Entry().Info("Wrong configuration has been detected: MultiPropertySet has been used. Please note that there is no official documentation for this usage. Please check the step documentation for more information")
}
for _, t := range s.Set {
log.Entry().Infof("Wrong configuration has been detected: %s has been used. This is currently not supported and this set will not be included in this run. Please check the step documentation for more information", t.Type)
}
objectSetString += `</osl:objectSet>`
}
return objectSetString
}
func fetchAUnitXcsrfToken(requestType string, details abaputils.ConnectionDetailsHTTP, body []byte, client piperhttp.Sender) (string, error) {
log.Entry().WithField("ABAP Endpoint: ", details.URL).Debug("Fetching Xcrsf-Token")
@ -538,10 +434,10 @@ func generateHTMLDocumentAUnit(parsedXML *AUnitResult) (htmlDocumentString strin
//AUnitConfig object for parsing yaml config of software components and packages
type AUnitConfig struct {
Title string `json:"title,omitempty"`
Context string `json:"context,omitempty"`
Options AUnitOptions `json:"options,omitempty"`
ObjectSet ObjectSet `json:"objectset,omitempty"`
Title string `json:"title,omitempty"`
Context string `json:"context,omitempty"`
Options AUnitOptions `json:"options,omitempty"`
ObjectSet abaputils.ObjectSet `json:"objectset,omitempty"`
}
//AUnitOptions in form of packages and software components to be checked
@ -572,124 +468,6 @@ type Duration struct {
Long *bool `json:"long,omitempty"`
}
//ObjectSet in form of packages and software components to be checked
type ObjectSet struct {
PackageNames []AUnitPackage `json:"packages,omitempty"`
SoftwareComponents []SoftwareComponents `json:"softwarecomponents,omitempty"`
Type string `json:"type,omitempty"`
MultiPropertySet MultiPropertySet `json:"multipropertyset,omitempty"`
Set []Set `json:"set,omitempty"`
}
//MultiPropertySet that can possibly contain any subsets/object of the OSL
type MultiPropertySet struct {
Type string `json:"type,omitempty"`
PackageNames []AUnitPackage `json:"packages,omitempty"`
ObjectTypeGroups []ObjectTypeGroup `json:"objecttypegroups,omitempty"`
ObjectTypes []ObjectType `json:"objecttypes,omitempty"`
Owners []Owner `json:"owners,omitempty"`
ReleaseStates []ReleaseState `json:"releasestates,omitempty"`
Versions []Version `json:"versions,omitempty"`
ApplicationComponents []ApplicationComponent `json:"applicationcomponents,omitempty"`
SoftwareComponents []SoftwareComponents `json:"softwarecomponents,omitempty"`
TransportLayers []TransportLayer `json:"transportlayers,omitempty"`
Languages []Language `json:"languages,omitempty"`
SourceSystems []SourceSystem `json:"sourcesystems,omitempty"`
}
//Set
type Set struct {
Type string `json:"type,omitempty"`
Set []Set `json:"set,omitempty"`
PackageSet []AUnitPackageSet `json:"package,omitempty"`
FlatObjectSet []AUnitFlatObjectSet `json:"object,omitempty"`
ComponentSet []AUnitComponentSet `json:"component,omitempty"`
TransportSet []AUnitTransportSet `json:"transport,omitempty"`
ObjectTypeSet []AUnitObjectTypeSet `json:"objecttype,omitempty"`
}
//AUnitPackageSet in form of packages to be checked
type AUnitPackageSet struct {
Name string `json:"name,omitempty"`
IncludeSubpackages *bool `json:"includesubpackages,omitempty"`
}
//AUnitFlatObjectSet
type AUnitFlatObjectSet struct {
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
}
//AUnitComponentSet in form of software components to be checked
type AUnitComponentSet struct {
Name string `json:"name,omitempty"`
}
//AUnitTransportSet in form of transports to be checked
type AUnitTransportSet struct {
Number string `json:"number,omitempty"`
}
//AUnitObjectTypeSet
type AUnitObjectTypeSet struct {
Name string `json:"name,omitempty"`
}
//AUnitPackage for MPS
type AUnitPackage struct {
Name string `json:"name,omitempty"`
}
//ObjectTypeGroup
type ObjectTypeGroup struct {
Name string `json:"name,omitempty"`
}
//ObjectType
type ObjectType struct {
Name string `json:"name,omitempty"`
}
//Owner
type Owner struct {
Name string `json:"name,omitempty"`
}
//ReleaseState
type ReleaseState struct {
Value string `json:"value,omitempty"`
}
//Version
type Version struct {
Value string `json:"value,omitempty"`
}
//ApplicationComponent
type ApplicationComponent struct {
Name string `json:"name,omitempty"`
}
//SoftwareComponents
type SoftwareComponents struct {
Name string `json:"name,omitempty"`
}
//TransportLayer
type TransportLayer struct {
Name string `json:"name,omitempty"`
}
//Language
type Language struct {
Value string `json:"value,omitempty"`
}
//SourceSystem
type SourceSystem struct {
Name string `json:"name,omitempty"`
}
//
// AUnit Run Structure
//

View File

@ -69,16 +69,16 @@ func TestBuildAUnitRequestBody(t *testing.T) {
Long: new(bool),
},
},
ObjectSet: ObjectSet{
ObjectSet: abaputils.ObjectSet{
Type: "testSet",
Set: []Set{
Set: []abaputils.Set{
{
Type: "testSet",
Set: []Set{
Set: []abaputils.Set{
{
Type: "testAUnitFlatObjectSet",
FlatObjectSet: []AUnitFlatObjectSet{
FlatObjectSet: []abaputils.FlatObjectSet{
{
Name: "TestCLAS",
Type: "CLAS",
@ -90,7 +90,7 @@ func TestBuildAUnitRequestBody(t *testing.T) {
},
{
Type: "testAUnitObjectTypeSet",
ObjectTypeSet: []AUnitObjectTypeSet{
ObjectTypeSet: []abaputils.ObjectTypeSet{
{
Name: "TestObjectType",
}},
@ -99,7 +99,7 @@ func TestBuildAUnitRequestBody(t *testing.T) {
},
}
objectSetString := buildAUnitObjectSetString(config)
objectSetString := abaputils.BuildOSLString(config.ObjectSet)
optionsString := buildAUnitOptionsString(config)
assert.Equal(t, expectedoptionsString, optionsString)
@ -132,10 +132,10 @@ func TestBuildAUnitRequestBody(t *testing.T) {
Long: new(bool),
},
},
ObjectSet: ObjectSet{
ObjectSet: abaputils.ObjectSet{
Type: "multiPropertySet",
MultiPropertySet: MultiPropertySet{
SoftwareComponents: []SoftwareComponents{
MultiPropertySet: abaputils.MultiPropertySet{
SoftwareComponents: []abaputils.SoftwareComponents{
{
Name: "testComponent1",
},
@ -147,7 +147,7 @@ func TestBuildAUnitRequestBody(t *testing.T) {
},
}
objectSetString := buildAUnitObjectSetString(config)
objectSetString := abaputils.BuildOSLString(config.ObjectSet)
optionsString := buildAUnitOptionsString(config)
assert.Equal(t, expectedoptionsString, optionsString)
@ -180,10 +180,10 @@ func TestBuildAUnitRequestBody(t *testing.T) {
Long: new(bool),
},
},
ObjectSet: ObjectSet{
ObjectSet: abaputils.ObjectSet{
Type: "",
MultiPropertySet: MultiPropertySet{
SoftwareComponents: []SoftwareComponents{
MultiPropertySet: abaputils.MultiPropertySet{
SoftwareComponents: []abaputils.SoftwareComponents{
{
Name: "testComponent1",
},
@ -195,7 +195,7 @@ func TestBuildAUnitRequestBody(t *testing.T) {
},
}
objectSetString := buildAUnitObjectSetString(config)
objectSetString := abaputils.BuildOSLString(config.ObjectSet)
optionsString := buildAUnitOptionsString(config)
assert.Equal(t, expectedoptionsString, optionsString)
@ -228,13 +228,13 @@ func TestBuildAUnitRequestBody(t *testing.T) {
Long: new(bool),
},
},
ObjectSet: ObjectSet{
PackageNames: []AUnitPackage{{
ObjectSet: abaputils.ObjectSet{
PackageNames: []abaputils.Package{{
Name: "testPackage1",
}, {
Name: "testPackage2",
}},
SoftwareComponents: []SoftwareComponents{{
SoftwareComponents: []abaputils.SoftwareComponents{{
Name: "testComponent1",
}, {
Name: "testComponent2",
@ -242,7 +242,7 @@ func TestBuildAUnitRequestBody(t *testing.T) {
},
}
objectSetString := buildAUnitObjectSetString(config)
objectSetString := abaputils.BuildOSLString(config.ObjectSet)
optionsString := buildAUnitOptionsString(config)
assert.Equal(t, expectedoptionsString, optionsString)
@ -254,11 +254,11 @@ func TestBuildAUnitRequestBody(t *testing.T) {
expectedoptionsString := `<aunit:options><aunit:measurements type="none"/><aunit:scope ownTests="true" foreignTests="true"/><aunit:riskLevel harmless="true" dangerous="true" critical="true"/><aunit:duration short="true" medium="true" long="true"/></aunit:options>`
config := AUnitConfig{Title: "Test", Context: "Test",
ObjectSet: ObjectSet{
PackageNames: []AUnitPackage{{
ObjectSet: abaputils.ObjectSet{
PackageNames: []abaputils.Package{{
Name: "testPackage1",
}},
SoftwareComponents: []SoftwareComponents{{
SoftwareComponents: []abaputils.SoftwareComponents{{
Name: "testComponent1",
}},
}}

209
pkg/abaputils/osl.go Normal file
View File

@ -0,0 +1,209 @@
package abaputils
import (
"reflect"
"github.com/SAP/jenkins-library/pkg/log"
)
//ObjectSet in form of packages and software components to be checked
type ObjectSet struct {
PackageNames []Package `json:"packages,omitempty"`
SoftwareComponents []SoftwareComponents `json:"softwarecomponents,omitempty"`
Type string `json:"type,omitempty"`
MultiPropertySet MultiPropertySet `json:"multipropertyset,omitempty"`
Set []Set `json:"set,omitempty"`
}
//MultiPropertySet that can possibly contain any subsets/object of the OSL
type MultiPropertySet struct {
Type string `json:"type,omitempty"`
PackageNames []Package `json:"packages,omitempty"`
PackageTrees []PackageTree `json:"packagetrees,omitempty"`
ObjectTypeGroups []ObjectTypeGroup `json:"objecttypegroups,omitempty"`
ObjectTypes []ObjectType `json:"objecttypes,omitempty"`
Owners []Owner `json:"owners,omitempty"`
ReleaseStates []ReleaseState `json:"releasestates,omitempty"`
Versions []Version `json:"versions,omitempty"`
ApplicationComponents []ApplicationComponent `json:"applicationcomponents,omitempty"`
SoftwareComponents []SoftwareComponents `json:"softwarecomponents,omitempty"`
TransportLayers []TransportLayer `json:"transportlayers,omitempty"`
Languages []Language `json:"languages,omitempty"`
SourceSystems []SourceSystem `json:"sourcesystems,omitempty"`
}
//Set
type Set struct {
Type string `json:"type,omitempty"`
Set []Set `json:"set,omitempty"`
PackageSet []PackageSet `json:"package,omitempty"`
FlatObjectSet []FlatObjectSet `json:"object,omitempty"`
ComponentSet []ComponentSet `json:"component,omitempty"`
TransportSet []TransportSet `json:"transport,omitempty"`
ObjectTypeSet []ObjectTypeSet `json:"objecttype,omitempty"`
}
//PackageSet in form of packages to be checked
type PackageSet struct {
Name string `json:"name,omitempty"`
IncludeSubpackages *bool `json:"includesubpackages,omitempty"`
}
//FlatObjectSet
type FlatObjectSet struct {
Name string `json:"name,omitempty"`
Type string `json:"type,omitempty"`
}
//ComponentSet in form of software components to be checked
type ComponentSet struct {
Name string `json:"name,omitempty"`
}
//TransportSet in form of transports to be checked
type TransportSet struct {
Number string `json:"number,omitempty"`
}
//ObjectTypeSet
type ObjectTypeSet struct {
Name string `json:"name,omitempty"`
}
//Package for MPS
type Package struct {
Name string `json:"name,omitempty"`
}
//Packagetree for MPS
type PackageTree struct {
Name string `json:"name,omitempty"`
}
//ObjectTypeGroup
type ObjectTypeGroup struct {
Name string `json:"name,omitempty"`
}
//ObjectType
type ObjectType struct {
Name string `json:"name,omitempty"`
}
//Owner
type Owner struct {
Name string `json:"name,omitempty"`
}
//ReleaseState
type ReleaseState struct {
Value string `json:"value,omitempty"`
}
//Version
type Version struct {
Value string `json:"value,omitempty"`
}
//ApplicationComponent
type ApplicationComponent struct {
Name string `json:"name,omitempty"`
}
//SoftwareComponents
type SoftwareComponents struct {
Name string `json:"name,omitempty"`
}
//TransportLayer
type TransportLayer struct {
Name string `json:"name,omitempty"`
}
//Language
type Language struct {
Value string `json:"value,omitempty"`
}
//SourceSystem
type SourceSystem struct {
Name string `json:"name,omitempty"`
}
func BuildOSLString(OSLConfig ObjectSet) (objectSetString string) {
//Build ObjectSets
s := OSLConfig
if s.Type == "" {
s.Type = "multiPropertySet"
}
switch s.Type {
case "multiPropertySet":
objectSetString += `<osl:objectSet xsi:type="` + s.Type + `" xmlns:osl="http://www.sap.com/api/osl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">`
if !(reflect.DeepEqual(s.PackageNames, Package{})) || !(reflect.DeepEqual(s.SoftwareComponents, SoftwareComponents{})) {
//To ensure Scomps and packages can be assigned on this level
mps := MultiPropertySet{
PackageNames: s.PackageNames,
SoftwareComponents: s.SoftwareComponents,
}
objectSetString += writeObjectSetProperties(mps)
}
objectSetString += writeObjectSetProperties(s.MultiPropertySet)
if !(reflect.DeepEqual(s.MultiPropertySet, MultiPropertySet{})) {
log.Entry().Info("Wrong configuration has been detected: MultiPropertySet has been used. Please note that there is no official documentation for this usage. Please check the step documentation for more information")
}
for _, t := range s.Set {
log.Entry().Infof("Wrong configuration has been detected: %s has been used. This is currently not supported and this set will not be included in this run. Please check the step documentation for more information", t.Type)
}
objectSetString += `</osl:objectSet>`
default:
log.Entry().Infof("Wrong configuration has been detected: %s has been used. This is currently not supported and this set will not be included in this run. Please check the step documentation for more information", s.Type)
}
return objectSetString
}
func writeObjectSetProperties(set MultiPropertySet) (objectSetString string) {
for _, packages := range set.PackageNames {
objectSetString += `<osl:package name="` + packages.Name + `"/>`
}
for _, packagetrees := range set.PackageTrees {
objectSetString += `<osl:package name="` + packagetrees.Name + `" includeSubpackages="true"/>`
}
for _, objectTypeGroup := range set.ObjectTypeGroups {
objectSetString += `<osl:objectTypeGroup name="` + objectTypeGroup.Name + `"/>`
}
for _, objectType := range set.ObjectTypes {
objectSetString += `<osl:objectType name="` + objectType.Name + `"/>`
}
for _, owner := range set.Owners {
objectSetString += `<osl:owner name="` + owner.Name + `"/>`
}
for _, releaseState := range set.ReleaseStates {
objectSetString += `<osl:releaseState value="` + releaseState.Value + `"/>`
}
for _, version := range set.Versions {
objectSetString += `<osl:version value="` + version.Value + `"/>`
}
for _, applicationComponent := range set.ApplicationComponents {
objectSetString += `<osl:applicationComponent name="` + applicationComponent.Name + `"/>`
}
for _, component := range set.SoftwareComponents {
objectSetString += `<osl:softwareComponent name="` + component.Name + `"/>`
}
for _, transportLayer := range set.TransportLayers {
objectSetString += `<osl:transportLayer name="` + transportLayer.Name + `"/>`
}
for _, language := range set.Languages {
objectSetString += `<osl:language value="` + language.Value + `"/>`
}
for _, sourceSystem := range set.SourceSystems {
objectSetString += `<osl:sourceSystem name="` + sourceSystem.Name + `"/>`
}
return objectSetString
}

View File

@ -9,7 +9,7 @@ metadata:
* The Cloud Foundry parameters (API endpoint, organization, space), credentials, the service instance for the ABAP service and the service key for the Communication Scenario SAP_COM_0510.
* Only provide one of those options with the respective credentials. If all values are provided, the direct communication (via host) has priority.
Regardless of the option you chose, please make sure to provide the configuration for Software Components and Packages that you want to be checked analog to the examples listed on this page.
Regardless of the option you chose, please make sure to provide the configuration the object set (e.g. with Software Components and Packages) that you want to be checked analog to the examples listed on this page.
spec:
inputs:
secrets:
@ -21,7 +21,7 @@ spec:
params:
- name: atcConfig
type: string
description: Path to a YAML configuration file for Packages and/or Software Components to be checked during ATC run
description: Path to a YAML configuration file for the object set to be checked during ATC run
scope:
- PARAMETERS
- STAGES