Skip to content

Commit

Permalink
abapEnvironmentAssemblePackages Unit Tests & Error Handling (#2654)
Browse files Browse the repository at this point in the history
* Unit Test Assemble Package

* Remove obsolete lines

dust wiping

* climate change

* climate change #2

* climate change #3

* climate change #4

* climate change #5

Co-authored-by: Daniel Mieg <[email protected]>
  • Loading branch information
tiloKo and DanielMieg authored Mar 1, 2021
1 parent 4ca9186 commit 218a743
Show file tree
Hide file tree
Showing 7 changed files with 1,680 additions and 62 deletions.
2 changes: 1 addition & 1 deletion cmd/abapEnvironmentAssembleConfirm.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ func abapEnvironmentAssembleConfirm(config abapEnvironmentAssembleConfirmOptions
}
}

func runAbapEnvironmentAssembleConfirm(config *abapEnvironmentAssembleConfirmOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client piperhttp.Sender, cpe *abapEnvironmentAssembleConfirmCommonPipelineEnvironment) error {
func runAbapEnvironmentAssembleConfirm(config *abapEnvironmentAssembleConfirmOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client abapbuild.HTTPSendLoader, cpe *abapEnvironmentAssembleConfirmCommonPipelineEnvironment) error {
conn := new(abapbuild.Connector)
var connConfig abapbuild.ConnectorConfiguration
connConfig.CfAPIEndpoint = config.CfAPIEndpoint
Expand Down
97 changes: 50 additions & 47 deletions cmd/abapEnvironmentAssemblePackages.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func abapEnvironmentAssemblePackages(config abapEnvironmentAssemblePackagesOptio
}
}

func runAbapEnvironmentAssemblePackages(config *abapEnvironmentAssemblePackagesOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client piperhttp.Sender, cpe *abapEnvironmentAssemblePackagesCommonPipelineEnvironment) error {
func runAbapEnvironmentAssemblePackages(config *abapEnvironmentAssemblePackagesOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client abapbuild.HTTPSendLoader, cpe *abapEnvironmentAssemblePackagesCommonPipelineEnvironment) error {
conn := new(abapbuild.Connector)
var connConfig abapbuild.ConnectorConfiguration
connConfig.CfAPIEndpoint = config.CfAPIEndpoint
Expand All @@ -54,31 +54,34 @@ func runAbapEnvironmentAssemblePackages(config *abapEnvironmentAssemblePackagesO

err := conn.InitBuildFramework(connConfig, com, client)
if err != nil {
return err
return errors.Wrap(err, "Connector initialization failed")
}

var addonDescriptor abaputils.AddonDescriptor
err = json.Unmarshal([]byte(config.AddonDescriptor), &addonDescriptor)
if err != nil {
return err
return errors.Wrap(err, "Reading AddonDescriptor failed [Make sure abapAddonAssemblyKit...CheckCVs|CheckPV|ReserveNextPackages steps have been run before]")
}

delayBetweenPostsInSeconds := time.Duration(3 * time.Second)
builds, buildsAlreadyReleased, err := starting(addonDescriptor.Repositories, *conn, delayBetweenPostsInSeconds)
if err != nil {
return err
return errors.Wrap(err, "Starting Builds failed")
}
maxRuntimeInMinutes := time.Duration(config.MaxRuntimeInMinutes) * time.Minute
pollIntervalsInSeconds := time.Duration(60 * time.Second)
err = polling(builds, maxRuntimeInMinutes, pollIntervalsInSeconds)
pollIntervalsInMilliseconds := time.Duration(config.PollIntervalsInMilliseconds) * time.Millisecond
err = polling(builds, maxRuntimeInMinutes, pollIntervalsInMilliseconds)
if err != nil {
return err
return errors.Wrap(err, "Polling failed")
}

err = checkIfFailedAndPrintLogs(builds)
if err != nil {
return err
return errors.Wrap(err, "Check if failed and Printing Logs failed")
}
reposBackToCPE, err := downloadSARXML(builds)
if err != nil {
return err
return errors.Wrap(err, "Download SAR XML failed")
}
// also write the already released packages back to cpe
for _, b := range buildsAlreadyReleased {
Expand All @@ -91,43 +94,6 @@ func runAbapEnvironmentAssemblePackages(config *abapEnvironmentAssemblePackagesO
return nil
}

func downloadSARXML(builds []buildWithRepository) ([]abaputils.Repository, error) {
var reposBackToCPE []abaputils.Repository
resultName := "SAR_XML"
envPath := filepath.Join(GeneralConfig.EnvRootPath, "commonPipelineEnvironment", "abap")
for i, b := range builds {
resultSARXML, err := b.build.GetResult(resultName)
if err != nil {
return reposBackToCPE, err
}
sarPackage := resultSARXML.AdditionalInfo
downloadPath := filepath.Join(envPath, path.Base(sarPackage))
log.Entry().Infof("Downloading SAR file %s to %s", path.Base(sarPackage), downloadPath)
err = resultSARXML.Download(downloadPath)
if err != nil {
return reposBackToCPE, err
}
builds[i].repo.SarXMLFilePath = downloadPath
reposBackToCPE = append(reposBackToCPE, builds[i].repo)
}
return reposBackToCPE, nil
}

func checkIfFailedAndPrintLogs(builds []buildWithRepository) error {
var buildFailed bool = false
for i := range builds {
if builds[i].build.RunState == abapbuild.Failed {
log.Entry().Errorf("Assembly of %s failed", builds[i].repo.PackageName)
buildFailed = true
}
builds[i].build.PrintLogs()
}
if buildFailed {
return errors.New("At least the assembly of one package failed")
}
return nil
}

func starting(repos []abaputils.Repository, conn abapbuild.Connector, delayBetweenPostsInSeconds time.Duration) ([]buildWithRepository, []buildWithRepository, error) {
var builds []buildWithRepository
var buildsAlreadyReleased []buildWithRepository
Expand Down Expand Up @@ -162,7 +128,7 @@ func polling(builds []buildWithRepository, maxRuntimeInMinutes time.Duration, po
for {
select {
case <-timeout:
return errors.New("Timed out")
return errors.Errorf("Timed out: (max Runtime %v reached)", maxRuntimeInMinutes)
case <-ticker:
var allFinished bool = true
for i := range builds {
Expand Down Expand Up @@ -212,3 +178,40 @@ func (b *buildWithRepository) start() error {
log.Entry().Infof("Starting assembly of package %s", b.repo.PackageName)
return b.build.Start(phase, valuesInput)
}

func checkIfFailedAndPrintLogs(builds []buildWithRepository) error {
var buildFailed bool = false
for i := range builds {
if builds[i].build.RunState == abapbuild.Failed {
log.Entry().Errorf("Assembly of %s failed", builds[i].repo.PackageName)
buildFailed = true
}
builds[i].build.PrintLogs()
}
if buildFailed {
return errors.New("At least the assembly of one package failed")
}
return nil
}

func downloadSARXML(builds []buildWithRepository) ([]abaputils.Repository, error) {
var reposBackToCPE []abaputils.Repository
resultName := "SAR_XML"
envPath := filepath.Join(GeneralConfig.EnvRootPath, "commonPipelineEnvironment", "abap")
for i, b := range builds {
resultSARXML, err := b.build.GetResult(resultName)
if err != nil {
return reposBackToCPE, err
}
sarPackage := resultSARXML.AdditionalInfo
downloadPath := filepath.Join(envPath, path.Base(sarPackage))
log.Entry().Infof("Downloading SAR file %s to %s", path.Base(sarPackage), downloadPath)
err = resultSARXML.Download(downloadPath)
if err != nil {
return reposBackToCPE, err
}
builds[i].repo.SarXMLFilePath = downloadPath
reposBackToCPE = append(reposBackToCPE, builds[i].repo)
}
return reposBackToCPE, nil
}
33 changes: 22 additions & 11 deletions cmd/abapEnvironmentAssemblePackages_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

96 changes: 96 additions & 0 deletions cmd/abapEnvironmentAssemblePackages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,99 @@ func TestDownloadSARXML(t *testing.T) {
assert.Equal(t, downloadPath, repos[0].SarXMLFilePath)
})
}

func TestStep(t *testing.T) {
t.Run("abapEnvironmentAssemblePackages: nothing to do", func(t *testing.T) {

config := &abapEnvironmentAssemblePackagesOptions{
AddonDescriptor: cpeAbapAddonDescriptorPackageLocked,
MaxRuntimeInMinutes: 1,
PollIntervalsInMilliseconds: 1,
}

autils := &abaputils.AUtilsMock{}
client := abapbuild.GetBuildMockClient()
cpe := &abapEnvironmentAssemblePackagesCommonPipelineEnvironment{}

err := runAbapEnvironmentAssemblePackages(config, nil, autils, &client, cpe)
assert.NoError(t, err)
})
t.Run("abapEnvironmentAssemblePackages: build", func(t *testing.T) {

config := &abapEnvironmentAssemblePackagesOptions{
AddonDescriptor: cpeAbapAddonDescriptorPackageReserved,
MaxRuntimeInMinutes: 1,
PollIntervalsInMilliseconds: 1,
}

autils := &abaputils.AUtilsMock{
ReturnedConnectionDetailsHTTP: abaputils.ConnectionDetailsHTTP{
URL: `/sap/opu/odata/BUILD/CORE_SRV`,
},
}

client := abapbuild.GetBuildMockClient()

cpe := &abapEnvironmentAssemblePackagesCommonPipelineEnvironment{}

err := runAbapEnvironmentAssemblePackages(config, nil, autils, &client, cpe)
assert.NoError(t, err)
assert.Contains(t, cpe.abap.addonDescriptor, `SAPK-001AAINITAPC1.SAR`)
})
}

var cpeAbapAddonDescriptorPackageLocked = `{
"addonProduct":"/ITAPC1/I_CURRENCZPRODUCT",
"addonVersion":"1.0.0",
"addonVersionAAK":"0001",
"addonUniqueID":"myAddonId",
"customerID":"$ID",
"AddonSpsLevel":"0000",
"AddonPatchLevel":"0000",
"TargetVectorID":"",
"repositories":[
{ "name":"/ITAPC1/I_CURRENCZ",
"tag":"whatever",
"branch":"",
"commitID":"",
"version":"1.0.0",
"versionAAK":"0001",
"PackageName":"SAPK-002AAINITAPC1",
"PackageType":"AOI",
"SpLevel":"0000",
"PatchLevel":"0000",
"PredecessorCommitID":"",
"Status":"L",
"Namespace":"/ITAPC1/",
"SarXMLFilePath":".pipeline\\commonPipelineEnvironment\\abap\\SAPK-002AAINITAPC1.SAR"
}
]
}`

var cpeAbapAddonDescriptorPackageReserved = `{
"addonProduct":"/ITAPC1/I_CURRENCZPRODUCT",
"addonVersion":"1.0.0",
"addonVersionAAK":"0001",
"addonUniqueID":"myAddonId",
"customerID":"$ID",
"AddonSpsLevel":"0000",
"AddonPatchLevel":"0000",
"TargetVectorID":"",
"repositories":[
{ "name":"/ITAPC1/I_CURRENCZ",
"tag":"whatever",
"branch":"",
"commitID":"",
"version":"1.0.0",
"versionAAK":"0001",
"PackageName":"SAPK-002AAINITAPC1",
"PackageType":"AOI",
"SpLevel":"0000",
"PatchLevel":"0000",
"PredecessorCommitID":"",
"Status":"P",
"Namespace":"/ITAPC1/",
"SarXMLFilePath":""
}
]
}`
10 changes: 8 additions & 2 deletions pkg/abap/build/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ type ConnectorConfiguration struct {
MaxRuntimeInMinutes int
}

// HTTPSendLoader : combine both interfaces [sender, downloader]
type HTTPSendLoader interface {
piperhttp.Sender
piperhttp.Downloader
}

// ******** technical communication calls ********

// GetToken : Get the X-CRSF Token from ABAP Backend for later post
Expand Down Expand Up @@ -124,13 +130,13 @@ func (conn *Connector) InitAAKaaS(aAKaaSEndpoint string, username string, passwo
}

// InitBuildFramework : initialize Connector for communication with ABAP SCP instance
func (conn *Connector) InitBuildFramework(config ConnectorConfiguration, com abaputils.Communication, inputclient piperhttp.Sender) error {
func (conn *Connector) InitBuildFramework(config ConnectorConfiguration, com abaputils.Communication, inputclient HTTPSendLoader) error {
conn.Client = inputclient
conn.Header = make(map[string][]string)
conn.Header["Accept"] = []string{"application/json"}
conn.Header["Content-Type"] = []string{"application/json"}

conn.DownloadClient = &piperhttp.Client{}
conn.DownloadClient = inputclient
conn.DownloadClient.SetOptions(piperhttp.ClientOptions{TransportTimeout: 20 * time.Second})
// Mapping for options
subOptions := abaputils.AbapEnvironmentOptions{}
Expand Down
Loading

0 comments on commit 218a743

Please sign in to comment.