mirror of
https://github.com/SAP/jenkins-library.git
synced 2025-02-21 19:48:53 +02:00
Refactor build framework steps (#2068)
* adding my steps * messy step * Update abapEnvironmentAssembly.go * clean up * change yaml * corrections * Update cloudFoundryDeploy.go * update * delete simulation step * remove simulate * Update PiperGoUtils.groovy * Update PiperGoUtils.groovy * Update CommonStepsTest.groovy * add docu * Update abapEnvironmentAssembly.md * changes due to PR * Update .gitignore * b * CV list * Update abapEnvironmentAssembly.go * testing with simulation * Update abapEnvironmentAssembly.go * remove simulation * renaming * Update mkdocs.yml * moving service key to yaml and fixing code climate * Update abapEnvironmentAssemblePackages.go * Update abapEnvironmentAssemblePackages.go * Update abapEnvironmentAssemblePackages.go * Update abapEnvironmentAssemblePackages.go * change input * Update abapEnvironmentAssemblePackages.go * change json tag * fixed error handling * documentation * Update abapEnvironmentAssemblePackages.md * Update abapEnvironmentAssemblePackages.md * fixing code climate issues * fixing code climate issues * Update abapEnvironmentAssemblePackages.yaml * fixing code climate issues * Update abapEnvironmentAssemblePackages.yaml * adding unittests * adding unittests and improved logging * yaml -> json * change scope of cfServiceKeyName * correct indentation * Update CommonStepsTest.groovy * maintain correct step order * Move Connector to connector.go * Refactor bfw with unit tests * remove spaces * CodeClimate Fix for unexported type * ABAP BF - Adding Error Handling Unmarshal * Revert Unmarshal Co-authored-by: rosemarieB <45030247+rosemarieB@users.noreply.github.com> Co-authored-by: Daniel Mieg <56156797+DanielMieg@users.noreply.github.com> Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> Co-authored-by: Koerner <tilo.koerner@sap.com> Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com>
This commit is contained in:
parent
b16f0428e1
commit
7a028c4149
@ -1,18 +1,12 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
|
||||
abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
|
||||
"github.com/SAP/jenkins-library/pkg/abaputils"
|
||||
"github.com/SAP/jenkins-library/pkg/command"
|
||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||
@ -21,6 +15,11 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type buildWithRepository struct {
|
||||
build abapbuild.Build
|
||||
repo abaputils.Repository
|
||||
}
|
||||
|
||||
func abapEnvironmentAssemblePackages(config abapEnvironmentAssemblePackagesOptions, telemetryData *telemetry.CustomData, cpe *abapEnvironmentAssemblePackagesCommonPipelineEnvironment) {
|
||||
// for command execution use Command
|
||||
c := command.Command{}
|
||||
@ -39,22 +38,25 @@ func abapEnvironmentAssemblePackages(config abapEnvironmentAssemblePackagesOptio
|
||||
}
|
||||
}
|
||||
|
||||
// *******************************************************************************************************************************
|
||||
// ********************************************************** Step logic *********************************************************
|
||||
// *******************************************************************************************************************************
|
||||
func runAbapEnvironmentAssemblePackages(config *abapEnvironmentAssemblePackagesOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client piperhttp.Sender, cpe *abapEnvironmentAssemblePackagesCommonPipelineEnvironment) error {
|
||||
conn := new(connector)
|
||||
err := conn.init(config, com, client)
|
||||
conn := new(abapbuild.Connector)
|
||||
var connConfig abapbuild.ConnectorConfiguration
|
||||
err := conn.InitBuildFramework(connConfig, com, client)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var addonDescriptor abaputils.AddonDescriptor
|
||||
json.Unmarshal([]byte(config.AddonDescriptor), &addonDescriptor)
|
||||
err = json.Unmarshal([]byte(config.AddonDescriptor), &addonDescriptor)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
builds, buildsAlreadyReleased, err := starting(addonDescriptor.Repositories, *conn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = polling(builds, time.Duration(config.MaxRuntimeInMinutes), 60)
|
||||
maxRuntimeInMinutes := time.Duration(config.MaxRuntimeInMinutes) * time.Minute
|
||||
pollIntervalsInSeconds := time.Duration(60 * time.Second)
|
||||
err = polling(builds, maxRuntimeInMinutes, pollIntervalsInSeconds)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -82,14 +84,14 @@ func downloadSARXML(builds []buildWithRepository) ([]abaputils.Repository, error
|
||||
resultName := "SAR_XML"
|
||||
envPath := filepath.Join(GeneralConfig.EnvRootPath, "commonPipelineEnvironment", "abap")
|
||||
for i, b := range builds {
|
||||
resultSARXML, err := b.build.getResult(resultName)
|
||||
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)
|
||||
err = resultSARXML.Download(downloadPath)
|
||||
if err != nil {
|
||||
return reposBackToCPE, err
|
||||
}
|
||||
@ -101,13 +103,12 @@ func downloadSARXML(builds []buildWithRepository) ([]abaputils.Repository, error
|
||||
|
||||
func checkIfFailedAndPrintLogs(builds []buildWithRepository) error {
|
||||
var buildFailed bool = false
|
||||
for _, bR := range builds {
|
||||
b := bR.build
|
||||
if b.RunState == failed {
|
||||
log.Entry().Errorf("Assembly of %s failed", b.BuildID)
|
||||
for i := range builds {
|
||||
if builds[i].build.RunState == abapbuild.Failed {
|
||||
log.Entry().Errorf("Assembly of %s failed", builds[i].repo.PackageName)
|
||||
buildFailed = true
|
||||
}
|
||||
b.printLogs()
|
||||
builds[i].build.PrintLogs()
|
||||
}
|
||||
if buildFailed {
|
||||
return errors.New("At least the assembly of one package failed")
|
||||
@ -115,12 +116,12 @@ func checkIfFailedAndPrintLogs(builds []buildWithRepository) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func starting(repos []abaputils.Repository, conn connector) ([]buildWithRepository, []buildWithRepository, error) {
|
||||
func starting(repos []abaputils.Repository, conn abapbuild.Connector) ([]buildWithRepository, []buildWithRepository, error) {
|
||||
var builds []buildWithRepository
|
||||
var buildsAlreadyReleased []buildWithRepository
|
||||
for _, repo := range repos {
|
||||
assemblyBuild := build{
|
||||
connector: conn,
|
||||
assemblyBuild := abapbuild.Build{
|
||||
Connector: conn,
|
||||
}
|
||||
buildRepo := buildWithRepository{
|
||||
build: assemblyBuild,
|
||||
@ -133,7 +134,7 @@ func starting(repos []abaputils.Repository, conn connector) ([]buildWithReposito
|
||||
}
|
||||
builds = append(builds, buildRepo)
|
||||
} else {
|
||||
log.Entry().Infof("Packages %s is already released. No need to run the assembly", repo.PackageName)
|
||||
log.Entry().Infof("Packages %s is in status '%s'. No need to run the assembly", repo.PackageName, repo.Status)
|
||||
buildsAlreadyReleased = append(buildsAlreadyReleased, buildRepo)
|
||||
}
|
||||
}
|
||||
@ -141,8 +142,8 @@ func starting(repos []abaputils.Repository, conn connector) ([]buildWithReposito
|
||||
}
|
||||
|
||||
func polling(builds []buildWithRepository, maxRuntimeInMinutes time.Duration, pollIntervalsInSeconds time.Duration) error {
|
||||
timeout := time.After(maxRuntimeInMinutes * time.Minute)
|
||||
ticker := time.Tick(pollIntervalsInSeconds * time.Second)
|
||||
timeout := time.After(maxRuntimeInMinutes)
|
||||
ticker := time.Tick(pollIntervalsInSeconds)
|
||||
for {
|
||||
select {
|
||||
case <-timeout:
|
||||
@ -150,12 +151,10 @@ func polling(builds []buildWithRepository, maxRuntimeInMinutes time.Duration, po
|
||||
case <-ticker:
|
||||
var allFinished bool = true
|
||||
for i := range builds {
|
||||
builds[i].build.Get()
|
||||
if !builds[i].build.IsFinished() {
|
||||
builds[i].build.get()
|
||||
if !builds[i].build.IsFinished() {
|
||||
log.Entry().Infof("Assembly of %s is not yet finished, check again in %02d seconds", builds[i].repo.PackageName, pollIntervalsInSeconds)
|
||||
allFinished = false
|
||||
}
|
||||
log.Entry().Infof("Assembly of %s is not yet finished, check again in %s", builds[i].repo.PackageName, pollIntervalsInSeconds)
|
||||
allFinished = false
|
||||
}
|
||||
}
|
||||
if allFinished {
|
||||
@ -169,8 +168,8 @@ func (b *buildWithRepository) start() error {
|
||||
if b.repo.Name == "" || b.repo.Version == "" || b.repo.SpLevel == "" || b.repo.Namespace == "" || b.repo.PackageType == "" || b.repo.PackageName == "" {
|
||||
return errors.New("Parameters missing. Please provide software component name, version, sp-level, namespace, packagetype and packagename")
|
||||
}
|
||||
valuesInput := values{
|
||||
Values: []value{
|
||||
valuesInput := abapbuild.Values{
|
||||
Values: []abapbuild.Value{
|
||||
{
|
||||
ValueID: "SWC",
|
||||
Value: b.repo.Name,
|
||||
@ -191,489 +190,10 @@ func (b *buildWithRepository) start() error {
|
||||
}
|
||||
if b.repo.PredecessorCommitID != "" {
|
||||
valuesInput.Values = append(valuesInput.Values,
|
||||
value{ValueID: "PREVIOUS_DELIVERY_COMMIT",
|
||||
abapbuild.Value{ValueID: "PREVIOUS_DELIVERY_COMMIT",
|
||||
Value: b.repo.PredecessorCommitID})
|
||||
}
|
||||
phase := "BUILD_" + b.repo.PackageType
|
||||
log.Entry().Infof("Starting assembly of package %s", b.repo.PackageName)
|
||||
return b.build.start(phase, valuesInput)
|
||||
}
|
||||
|
||||
type buildWithRepository struct {
|
||||
build build
|
||||
repo abaputils.Repository
|
||||
}
|
||||
|
||||
// *******************************************************************************************************************************
|
||||
// ************************************************************ REUSE ************************************************************
|
||||
// *******************************************************************************************************************************
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* Funcs *******************************
|
||||
// *********************************************************************
|
||||
|
||||
// ******** technical communication settings ********
|
||||
|
||||
func (conn *connector) init(config *abapEnvironmentAssemblePackagesOptions, com abaputils.Communication, inputclient piperhttp.Sender) 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.SetOptions(piperhttp.ClientOptions{TransportTimeout: 20 * time.Second})
|
||||
// Mapping for options
|
||||
subOptions := abaputils.AbapEnvironmentOptions{}
|
||||
subOptions.CfAPIEndpoint = config.CfAPIEndpoint
|
||||
subOptions.CfServiceInstance = config.CfServiceInstance
|
||||
subOptions.CfServiceKeyName = config.CfServiceKeyName
|
||||
subOptions.CfOrg = config.CfOrg
|
||||
subOptions.CfSpace = config.CfSpace
|
||||
subOptions.Host = config.Host
|
||||
subOptions.Password = config.Password
|
||||
subOptions.Username = config.Username
|
||||
|
||||
// Determine the host, user and password, either via the input parameters or via a cloud foundry service key
|
||||
connectionDetails, err := com.GetAbapCommunicationArrangementInfo(subOptions, "/sap/opu/odata/BUILD/CORE_SRV")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Parameters for the ABAP Connection not available")
|
||||
}
|
||||
|
||||
conn.DownloadClient.SetOptions(piperhttp.ClientOptions{
|
||||
Username: connectionDetails.User,
|
||||
Password: connectionDetails.Password,
|
||||
})
|
||||
cookieJar, _ := cookiejar.New(nil)
|
||||
conn.Client.SetOptions(piperhttp.ClientOptions{
|
||||
Username: connectionDetails.User,
|
||||
Password: connectionDetails.Password,
|
||||
CookieJar: cookieJar,
|
||||
})
|
||||
conn.Baseurl = connectionDetails.URL
|
||||
return nil
|
||||
}
|
||||
|
||||
// ******** technical communication calls ********
|
||||
|
||||
func (conn *connector) getToken(appendum string) error {
|
||||
url := conn.Baseurl + appendum
|
||||
conn.Header["X-CSRF-Token"] = []string{"Fetch"}
|
||||
response, err := conn.Client.SendRequest("HEAD", url, nil, conn.Header, nil)
|
||||
if err != nil {
|
||||
if response == nil {
|
||||
return errors.Wrap(err, "Fetching X-CSRF-Token failed")
|
||||
}
|
||||
defer response.Body.Close()
|
||||
errorbody, _ := ioutil.ReadAll(response.Body)
|
||||
return errors.Wrapf(err, "Fetching X-CSRF-Token failed: %v", string(errorbody))
|
||||
|
||||
}
|
||||
defer response.Body.Close()
|
||||
token := response.Header.Get("X-CSRF-Token")
|
||||
conn.Header["X-CSRF-Token"] = []string{token}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (conn connector) get(appendum string) ([]byte, error) {
|
||||
url := conn.Baseurl + appendum
|
||||
response, err := conn.Client.SendRequest("GET", url, nil, conn.Header, nil)
|
||||
if err != nil {
|
||||
if response == nil {
|
||||
return nil, errors.Wrap(err, "Get failed")
|
||||
}
|
||||
defer response.Body.Close()
|
||||
errorbody, _ := ioutil.ReadAll(response.Body)
|
||||
return errorbody, errors.Wrapf(err, "Get failed: %v", string(errorbody))
|
||||
|
||||
}
|
||||
defer response.Body.Close()
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
return body, err
|
||||
}
|
||||
|
||||
func (conn connector) post(appendum string, importBody string) ([]byte, error) {
|
||||
url := conn.Baseurl + appendum
|
||||
var response *http.Response
|
||||
var err error
|
||||
if importBody == "" {
|
||||
response, err = conn.Client.SendRequest("POST", url, nil, conn.Header, nil)
|
||||
} else {
|
||||
response, err = conn.Client.SendRequest("POST", url, bytes.NewBuffer([]byte(importBody)), conn.Header, nil)
|
||||
}
|
||||
if err != nil {
|
||||
if response == nil {
|
||||
return nil, errors.Wrap(err, "Post failed")
|
||||
}
|
||||
defer response.Body.Close()
|
||||
errorbody, _ := ioutil.ReadAll(response.Body)
|
||||
return errorbody, errors.Wrapf(err, "Post failed: %v", string(errorbody))
|
||||
|
||||
}
|
||||
defer response.Body.Close()
|
||||
body, err := ioutil.ReadAll(response.Body)
|
||||
return body, err
|
||||
}
|
||||
|
||||
func (conn connector) download(appendum string, downloadPath string) error {
|
||||
url := conn.Baseurl + appendum
|
||||
err := conn.DownloadClient.DownloadFile(url, downloadPath, nil, nil)
|
||||
return err
|
||||
}
|
||||
|
||||
// ******** BUILD logic ********
|
||||
|
||||
func (b *build) start(phase string, inputValues values) error {
|
||||
if err := b.getToken(""); err != nil {
|
||||
return err
|
||||
}
|
||||
importBody := inputForPost{
|
||||
phase: phase,
|
||||
values: inputValues,
|
||||
}.String()
|
||||
|
||||
body, err := b.connector.post("/builds", importBody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var jBuild jsonBuild
|
||||
json.Unmarshal(body, &jBuild)
|
||||
b.BuildID = jBuild.Build.BuildID
|
||||
b.RunState = jBuild.Build.RunState
|
||||
b.ResultState = jBuild.Build.ResultState
|
||||
b.Phase = jBuild.Build.Phase
|
||||
b.Entitytype = jBuild.Build.Entitytype
|
||||
b.Startedby = jBuild.Build.Startedby
|
||||
b.StartedAt = jBuild.Build.StartedAt
|
||||
b.FinishedAt = jBuild.Build.FinishedAt
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *build) get() error {
|
||||
appendum := "/builds('" + b.BuildID + "')"
|
||||
body, err := b.connector.get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jBuild jsonBuild
|
||||
json.Unmarshal(body, &jBuild)
|
||||
b.RunState = jBuild.Build.RunState
|
||||
b.ResultState = jBuild.Build.ResultState
|
||||
b.Phase = jBuild.Build.Phase
|
||||
b.Entitytype = jBuild.Build.Entitytype
|
||||
b.Startedby = jBuild.Build.Startedby
|
||||
b.StartedAt = jBuild.Build.StartedAt
|
||||
b.FinishedAt = jBuild.Build.FinishedAt
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *build) getTasks() error {
|
||||
if len(b.Tasks) == 0 {
|
||||
appendum := "/builds('" + b.BuildID + "')/tasks"
|
||||
body, err := b.connector.get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jTasks jsonTasks
|
||||
json.Unmarshal(body, &jTasks)
|
||||
b.Tasks = jTasks.ResultTasks.Tasks
|
||||
sort.Slice(b.Tasks, func(i, j int) bool {
|
||||
return b.Tasks[i].TaskID < b.Tasks[j].TaskID
|
||||
})
|
||||
for i := range b.Tasks {
|
||||
b.Tasks[i].connector = b.connector
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *build) getValues() error {
|
||||
if len(b.Values) == 0 {
|
||||
appendum := "/builds('" + b.BuildID + "')/values"
|
||||
body, err := b.connector.get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jValues jsonValues
|
||||
json.Unmarshal(body, &jValues)
|
||||
b.Values = jValues.ResultValues.Values
|
||||
for i := range b.Values {
|
||||
b.Values[i].connector = b.connector
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *build) getLogs() error {
|
||||
if err := b.getTasks(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range b.Tasks {
|
||||
if err := b.Tasks[i].getLogs(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *build) printLogs() error {
|
||||
if err := b.getTasks(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range b.Tasks {
|
||||
if err := b.Tasks[i].printLogs(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *build) getResults() error {
|
||||
if err := b.getTasks(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range b.Tasks {
|
||||
if err := b.Tasks[i].getResults(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *task) printLogs() error {
|
||||
if err := t.getLogs(); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, logs := range t.Logs {
|
||||
logs.print()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *build) getResult(name string) (result, error) {
|
||||
var Results []result
|
||||
var returnResult result
|
||||
if err := b.getResults(); err != nil {
|
||||
return returnResult, err
|
||||
}
|
||||
for _, task := range b.Tasks {
|
||||
for _, result := range task.Results {
|
||||
if result.Name == name {
|
||||
Results = append(Results, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
switch len(Results) {
|
||||
case 0:
|
||||
return returnResult, errors.New("No result named " + name + " was found")
|
||||
case 1:
|
||||
return Results[0], nil
|
||||
default:
|
||||
return returnResult, errors.New("More than one result with the name " + name + " was found")
|
||||
}
|
||||
}
|
||||
|
||||
func (b *build) IsFinished() bool {
|
||||
if b.RunState == finished || b.RunState == failed {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *task) getLogs() error {
|
||||
if len(t.Logs) == 0 {
|
||||
appendum := fmt.Sprint("/tasks(build_id='", t.BuildID, "',task_id=", t.TaskID, ")/logs")
|
||||
body, err := t.connector.get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jLogs jsonLogs
|
||||
json.Unmarshal(body, &jLogs)
|
||||
t.Logs = jLogs.ResultLogs.Logs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *task) getResults() error {
|
||||
if len(t.Results) == 0 {
|
||||
appendum := fmt.Sprint("/tasks(build_id='", t.BuildID, "',task_id=", t.TaskID, ")/results")
|
||||
body, err := t.connector.get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jResults jsonResults
|
||||
json.Unmarshal(body, &jResults)
|
||||
t.Results = jResults.ResultResults.Results
|
||||
for i := range t.Results {
|
||||
t.Results[i].connector = t.connector
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (result *result) download(downloadPath string) error {
|
||||
appendum := fmt.Sprint("/results(build_id='", result.BuildID, "',task_id=", result.TaskID, ",name='", result.Name, "')/$value")
|
||||
err := result.connector.download(appendum, downloadPath)
|
||||
return err
|
||||
}
|
||||
|
||||
func (logging *logStruct) print() {
|
||||
switch logging.Msgty {
|
||||
case loginfo:
|
||||
log.Entry().WithField("Timestamp", logging.Timestamp).Info(logging.Logline)
|
||||
case logwarning:
|
||||
log.Entry().WithField("Timestamp", logging.Timestamp).Warn(logging.Logline)
|
||||
case logerror:
|
||||
log.Entry().WithField("Timestamp", logging.Timestamp).Error(logging.Logline)
|
||||
case logaborted:
|
||||
log.Entry().WithField("Timestamp", logging.Timestamp).Error(logging.Logline)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// ******** parsing ********
|
||||
func (v value) String() string {
|
||||
return fmt.Sprintf(
|
||||
`{ "value_id": "%s", "value": "%s" }`,
|
||||
v.ValueID,
|
||||
v.Value)
|
||||
}
|
||||
|
||||
func (vs values) String() string {
|
||||
returnString := ""
|
||||
for _, value := range vs.Values {
|
||||
returnString = returnString + value.String() + ",\n"
|
||||
}
|
||||
returnString = returnString[:len(returnString)-2] //removes last ,
|
||||
return returnString
|
||||
}
|
||||
|
||||
func (in inputForPost) String() string {
|
||||
return fmt.Sprintf(`{ "phase": "%s", "values": [%s]}`, in.phase, in.values.String())
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ****************************** Structs ******************************
|
||||
// *********************************************************************
|
||||
|
||||
type resultState string
|
||||
type runState string
|
||||
type msgty string
|
||||
|
||||
const (
|
||||
successful resultState = "SUCCESSFUL"
|
||||
warning resultState = "WARNING"
|
||||
erroneous resultState = "ERRONEOUS"
|
||||
aborted resultState = "ABORTED"
|
||||
initializing runState = "INITIALIZING"
|
||||
accepted runState = "ACCEPTED"
|
||||
running runState = "RUNNING"
|
||||
finished runState = "FINISHED"
|
||||
failed runState = "FAILED"
|
||||
loginfo msgty = "I"
|
||||
logwarning msgty = "W"
|
||||
logerror msgty = "E"
|
||||
logaborted msgty = "A"
|
||||
)
|
||||
|
||||
type connector struct {
|
||||
Client piperhttp.Sender
|
||||
DownloadClient piperhttp.Downloader
|
||||
Header map[string][]string
|
||||
Baseurl string
|
||||
}
|
||||
|
||||
//******** structs needed for json conversion ********
|
||||
|
||||
type jsonBuild struct {
|
||||
Build *build `json:"d"`
|
||||
}
|
||||
|
||||
type jsonTasks struct {
|
||||
ResultTasks struct {
|
||||
Tasks []task `json:"results"`
|
||||
} `json:"d"`
|
||||
}
|
||||
|
||||
type jsonLogs struct {
|
||||
ResultLogs struct {
|
||||
Logs []logStruct `json:"results"`
|
||||
} `json:"d"`
|
||||
}
|
||||
|
||||
type jsonResults struct {
|
||||
ResultResults struct {
|
||||
Results []result `json:"results"`
|
||||
} `json:"d"`
|
||||
}
|
||||
|
||||
type jsonValues struct {
|
||||
ResultValues struct {
|
||||
Values []value `json:"results"`
|
||||
} `json:"d"`
|
||||
}
|
||||
|
||||
// ******** resembling data model in backend ********
|
||||
|
||||
type build struct {
|
||||
connector
|
||||
BuildID string `json:"build_id"`
|
||||
RunState runState `json:"run_state"`
|
||||
ResultState resultState `json:"result_state"`
|
||||
Phase string `json:"phase"`
|
||||
Entitytype string `json:"entitytype"`
|
||||
Startedby string `json:"startedby"`
|
||||
StartedAt string `json:"started_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
Tasks []task
|
||||
Values []value
|
||||
}
|
||||
|
||||
type task struct {
|
||||
connector
|
||||
BuildID string `json:"build_id"`
|
||||
TaskID int `json:"task_id"`
|
||||
LogID string `json:"log_id"`
|
||||
PluginClass string `json:"plugin_class"`
|
||||
StartedAt string `json:"started_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
ResultState resultState `json:"result_state"`
|
||||
Logs []logStruct
|
||||
Results []result
|
||||
}
|
||||
|
||||
type logStruct struct {
|
||||
BuildID string `json:"build_id"`
|
||||
TaskID int `json:"task_id"`
|
||||
LogID string `json:"log_id"`
|
||||
Msgty msgty `json:"msgty"`
|
||||
Detlevel string `json:"detlevel"`
|
||||
Logline string `json:"log_line"`
|
||||
Timestamp string `json:"TIME_STMP"`
|
||||
}
|
||||
|
||||
type result struct {
|
||||
connector
|
||||
BuildID string `json:"build_id"`
|
||||
TaskID int `json:"task_id"`
|
||||
Name string `json:"name"`
|
||||
AdditionalInfo string `json:"additional_info"`
|
||||
Mimetype string `json:"mimetype"`
|
||||
}
|
||||
|
||||
type value struct {
|
||||
connector
|
||||
BuildID string `json:"build_id"`
|
||||
ValueID string `json:"value_id"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// ******** import structure to post call ********
|
||||
|
||||
type inputForPost struct {
|
||||
phase string
|
||||
values values
|
||||
}
|
||||
|
||||
type values struct {
|
||||
Values []value `json:"results"`
|
||||
return b.build.Start(phase, valuesInput)
|
||||
}
|
||||
|
@ -1,27 +1,23 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
abapbuild "github.com/SAP/jenkins-library/pkg/abap/build"
|
||||
"github.com/SAP/jenkins-library/pkg/abaputils"
|
||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
func testSetup(client piperhttp.Sender, buildID string) build {
|
||||
conn := new(connector)
|
||||
func testSetup(client piperhttp.Sender, buildID string) abapbuild.Build {
|
||||
conn := new(abapbuild.Connector)
|
||||
conn.Client = client
|
||||
conn.DownloadClient = &downloadClientMock{}
|
||||
conn.DownloadClient = &abapbuild.DownloadClientMock{}
|
||||
conn.Header = make(map[string][]string)
|
||||
b := build{
|
||||
connector: *conn,
|
||||
b := abapbuild.Build{
|
||||
Connector: *conn,
|
||||
BuildID: buildID,
|
||||
}
|
||||
return b
|
||||
@ -30,8 +26,8 @@ func testSetup(client piperhttp.Sender, buildID string) build {
|
||||
func TestCheckIfFailedAndPrintLogsWithError(t *testing.T) {
|
||||
t.Run("checkIfFailedAndPrintLogs with failed build", func(t *testing.T) {
|
||||
var repo abaputils.Repository
|
||||
b := testSetup(&clMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
b.RunState = failed
|
||||
b := testSetup(&abapbuild.ClMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
b.RunState = abapbuild.Failed
|
||||
var buildsWithRepo []buildWithRepository
|
||||
bWR := buildWithRepository{
|
||||
build: b,
|
||||
@ -46,8 +42,8 @@ func TestCheckIfFailedAndPrintLogsWithError(t *testing.T) {
|
||||
func TestCheckIfFailedAndPrintLogs(t *testing.T) {
|
||||
t.Run("checkIfFailedAndPrintLogs", func(t *testing.T) {
|
||||
var repo abaputils.Repository
|
||||
b := testSetup(&clMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
b.RunState = finished
|
||||
b := testSetup(&abapbuild.ClMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
b.RunState = abapbuild.Finished
|
||||
var buildsWithRepo []buildWithRepository
|
||||
bWR := buildWithRepository{
|
||||
build: b,
|
||||
@ -61,10 +57,10 @@ func TestCheckIfFailedAndPrintLogs(t *testing.T) {
|
||||
|
||||
func TestStarting(t *testing.T) {
|
||||
t.Run("Run starting", func(t *testing.T) {
|
||||
client := &clMock{
|
||||
client := &abapbuild.ClMock{
|
||||
Token: "MyToken",
|
||||
}
|
||||
conn := new(connector)
|
||||
conn := new(abapbuild.Connector)
|
||||
conn.Client = client
|
||||
conn.Header = make(map[string][]string)
|
||||
var repos []abaputils.Repository
|
||||
@ -86,17 +82,17 @@ func TestStarting(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(builds))
|
||||
assert.Equal(t, 1, len(buildsAlreadyReleased))
|
||||
assert.Equal(t, accepted, builds[0].build.RunState)
|
||||
assert.Equal(t, runState(""), buildsAlreadyReleased[0].build.RunState)
|
||||
assert.Equal(t, abapbuild.Accepted, builds[0].build.RunState)
|
||||
assert.Equal(t, abapbuild.RunState(""), buildsAlreadyReleased[0].build.RunState)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStartingInvalidInput(t *testing.T) {
|
||||
t.Run("Run starting", func(t *testing.T) {
|
||||
client := &clMock{
|
||||
client := &abapbuild.ClMock{
|
||||
Token: "MyToken",
|
||||
}
|
||||
conn := new(connector)
|
||||
conn := new(abapbuild.Connector)
|
||||
conn.Client = client
|
||||
conn.Header = make(map[string][]string)
|
||||
var repos []abaputils.Repository
|
||||
@ -113,23 +109,25 @@ func TestStartingInvalidInput(t *testing.T) {
|
||||
func TestPolling(t *testing.T) {
|
||||
t.Run("Run polling", func(t *testing.T) {
|
||||
var repo abaputils.Repository
|
||||
b := testSetup(&clMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
b := testSetup(&abapbuild.ClMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
var buildsWithRepo []buildWithRepository
|
||||
bWR := buildWithRepository{
|
||||
build: b,
|
||||
repo: repo,
|
||||
}
|
||||
buildsWithRepo = append(buildsWithRepo, bWR)
|
||||
err := polling(buildsWithRepo, 600, 1)
|
||||
timeout := time.Duration(600 * time.Second)
|
||||
pollInterval := time.Duration(1 * time.Second)
|
||||
err := polling(buildsWithRepo, timeout, pollInterval)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, finished, buildsWithRepo[0].build.RunState)
|
||||
assert.Equal(t, abapbuild.Finished, buildsWithRepo[0].build.RunState)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDownloadSARXML(t *testing.T) {
|
||||
t.Run("Run downloadSARXML", func(t *testing.T) {
|
||||
var repo abaputils.Repository
|
||||
b := testSetup(&clMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
b := testSetup(&abapbuild.ClMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
var buildsWithRepo []buildWithRepository
|
||||
bWR := buildWithRepository{
|
||||
build: b,
|
||||
@ -142,430 +140,3 @@ func TestDownloadSARXML(t *testing.T) {
|
||||
assert.Equal(t, downloadPath, repos[0].SarXMLFilePath)
|
||||
})
|
||||
}
|
||||
|
||||
// *******************************************************************************************************************************
|
||||
// ************************************************* Tests for REUSE Part ********************************************************
|
||||
// *******************************************************************************************************************************
|
||||
|
||||
func TestSTart(t *testing.T) {
|
||||
t.Run("Run start", func(t *testing.T) {
|
||||
client := &clMock{
|
||||
Token: "MyToken",
|
||||
}
|
||||
b := testSetup(client, "")
|
||||
inputValues := values{
|
||||
Values: []value{
|
||||
{
|
||||
ValueID: "PACKAGES",
|
||||
Value: "/BUILD/CORE",
|
||||
},
|
||||
{
|
||||
ValueID: "season",
|
||||
Value: "winter",
|
||||
},
|
||||
},
|
||||
}
|
||||
err := b.start("test", inputValues)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, accepted, b.RunState)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
t.Run("Run Get", func(t *testing.T) {
|
||||
b := testSetup(&clMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
err := b.get()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, finished, b.RunState)
|
||||
assert.Equal(t, 0, len(b.Tasks))
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetTasks(t *testing.T) {
|
||||
t.Run("Run getTasks", func(t *testing.T) {
|
||||
b := testSetup(&clMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
assert.Equal(t, 0, len(b.Tasks))
|
||||
err := b.getTasks()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, b.Tasks[0].TaskID, 0)
|
||||
assert.Equal(t, b.Tasks[0].PluginClass, "")
|
||||
assert.Equal(t, b.Tasks[1].TaskID, 1)
|
||||
assert.Equal(t, b.Tasks[1].PluginClass, "/BUILD/CL_TEST_PLUGIN_OK")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetLogs(t *testing.T) {
|
||||
t.Run("Run getLogs", func(t *testing.T) {
|
||||
b := testSetup(&clMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
err := b.getLogs()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "I:/BUILD/LOG:000 ABAP Build Framework", b.Tasks[0].Logs[0].Logline)
|
||||
assert.Equal(t, loginfo, b.Tasks[0].Logs[0].Msgty)
|
||||
assert.Equal(t, "W:/BUILD/LOG:000 We can even have warnings!", b.Tasks[1].Logs[1].Logline)
|
||||
assert.Equal(t, logwarning, b.Tasks[1].Logs[1].Msgty)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetValues(t *testing.T) {
|
||||
t.Run("Run getValues", func(t *testing.T) {
|
||||
b := testSetup(&clMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
assert.Equal(t, 0, len(b.Values))
|
||||
err := b.getValues()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 4, len(b.Values))
|
||||
assert.Equal(t, "PHASE", b.Values[0].ValueID)
|
||||
assert.Equal(t, "test1", b.Values[0].Value)
|
||||
assert.Equal(t, "PACKAGES", b.Values[1].ValueID)
|
||||
assert.Equal(t, "/BUILD/CORE", b.Values[1].Value)
|
||||
assert.Equal(t, "season", b.Values[2].ValueID)
|
||||
assert.Equal(t, "winter", b.Values[2].Value)
|
||||
assert.Equal(t, "SUN", b.Values[3].ValueID)
|
||||
assert.Equal(t, "FLOWER", b.Values[3].Value)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetResults(t *testing.T) {
|
||||
t.Run("Run getResults", func(t *testing.T) {
|
||||
b := testSetup(&clMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
err := b.getResults()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(b.Tasks[0].Results))
|
||||
assert.Equal(t, 2, len(b.Tasks[1].Results))
|
||||
assert.Equal(t, "image/jpeg", b.Tasks[1].Results[0].Mimetype)
|
||||
assert.Equal(t, "application/octet-stream", b.Tasks[1].Results[1].Mimetype)
|
||||
|
||||
_, err = b.getResult("does_not_exist")
|
||||
assert.Error(t, err)
|
||||
r, err := b.getResult("SAR_XML")
|
||||
assert.Equal(t, "application/octet-stream", r.Mimetype)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
type downloadClientMock struct{}
|
||||
|
||||
func (dc *downloadClientMock) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dc *downloadClientMock) SetOptions(opts piperhttp.ClientOptions) {}
|
||||
|
||||
type clMock struct {
|
||||
Token string
|
||||
StatusCode int
|
||||
Error error
|
||||
}
|
||||
|
||||
func (c *clMock) SetOptions(opts piperhttp.ClientOptions) {}
|
||||
|
||||
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" {
|
||||
var body []byte
|
||||
body = []byte(fakeResponse(method, url))
|
||||
return &http.Response{
|
||||
StatusCode: c.StatusCode,
|
||||
Body: ioutil.NopCloser(bytes.NewReader(body)),
|
||||
}, c.Error
|
||||
} else if method == "HEAD" {
|
||||
var body []byte
|
||||
header := http.Header{}
|
||||
header.Set("X-Csrf-Token", c.Token)
|
||||
body = []byte("")
|
||||
return &http.Response{
|
||||
StatusCode: c.StatusCode,
|
||||
Header: header,
|
||||
Body: ioutil.NopCloser(bytes.NewReader(body)),
|
||||
}, c.Error
|
||||
} else {
|
||||
return nil, c.Error
|
||||
}
|
||||
}
|
||||
|
||||
func fakeResponse(method string, url string) string {
|
||||
if method == "POST" {
|
||||
return responsePOST
|
||||
}
|
||||
if strings.HasSuffix(url, "/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')") {
|
||||
return responseGetBuild
|
||||
} else if strings.HasSuffix(url, "/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')/tasks") {
|
||||
return responseGetTasks
|
||||
} else if strings.HasSuffix(url, "/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)/logs") {
|
||||
return ResponseGetLog0
|
||||
} else if strings.HasSuffix(url, "/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)/logs") {
|
||||
return ResponseGetLog1
|
||||
} else if strings.HasSuffix(url, "/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')/values") {
|
||||
return responseGetValues
|
||||
} else if strings.HasSuffix(url, "tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)/results") {
|
||||
return responseGetResults0
|
||||
} else if strings.HasSuffix(url, "tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)/results") {
|
||||
return responseGetResults1
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var responseGetBuild = `{
|
||||
"d": {
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_BUILDSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"run_state": "FINISHED",
|
||||
"result_state": "SUCCESSFUL",
|
||||
"phase": "test1",
|
||||
"entitytype": "P",
|
||||
"startedby": "BENTELER",
|
||||
"started_at": "/Date(1591718108103+0000)/",
|
||||
"finished_at": "/Date(1591718129432+0000)/",
|
||||
"tasks": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')/tasks"
|
||||
}
|
||||
},
|
||||
"values": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')/values"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
var responsePOST = `{
|
||||
"d": {
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPNVMOUQL2LHUFAUA')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPNVMOUQL2LHUFAUA')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_BUILDSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"run_state": "ACCEPTED",
|
||||
"result_state": "",
|
||||
"phase": "test1",
|
||||
"entitytype": "",
|
||||
"startedby": "BENTELER",
|
||||
"started_at": null,
|
||||
"finished_at": null,
|
||||
"tasks": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPNVMOUQL2LHUFAUA')/tasks"
|
||||
}
|
||||
},
|
||||
"values": {
|
||||
"results": []
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetTasks = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_TASKSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_1",
|
||||
"plugin_class": "/BUILD/CL_TEST_PLUGIN_OK",
|
||||
"started_at": "/Date(1591718128730+0000)/",
|
||||
"finished_at": "/Date(1591718129369+0000)/",
|
||||
"result_state": "SUCCESSFUL",
|
||||
"logs": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)/logs"
|
||||
}
|
||||
},
|
||||
"results": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)/results"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_TASKSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 0,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_0",
|
||||
"plugin_class": "",
|
||||
"started_at": "/Date(1591718128728+0000)/",
|
||||
"finished_at": "/Date(1591718129462+0000)/",
|
||||
"result_state": "SUCCESSFUL",
|
||||
"logs": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)/logs"
|
||||
}
|
||||
},
|
||||
"results": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)/results"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
var ResponseGetLog0 = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_0')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_0')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_LOGSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 0,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_0",
|
||||
"msgty": "I",
|
||||
"detlevel": "3",
|
||||
"log_line": "I:/BUILD/LOG:000 ABAP Build Framework",
|
||||
"TIME_STMP": "20200721133523"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_0')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_0')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_LOGSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 0,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_0",
|
||||
"msgty": "I",
|
||||
"detlevel": "3",
|
||||
"log_line": "I:/BUILD/LOG:000 ... Build Execution finished SUCCESSFUL",
|
||||
"TIME_STMP": "20200721133528"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
var ResponseGetLog1 = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_1')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_1')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_LOGSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_1",
|
||||
"msgty": "I",
|
||||
"detlevel": "1",
|
||||
"log_line": "I:/BUILD/LOG:000 Hello Packages [1]: , /BUILD/CORE, here is your lovely test_ok plugin!",
|
||||
"TIME_STMP": "20200721133528"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_1')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_1')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_LOGSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_1",
|
||||
"msgty": "W",
|
||||
"detlevel": "3",
|
||||
"log_line": "W:/BUILD/LOG:000 We can even have warnings!",
|
||||
"TIME_STMP": "20200721133528"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetResults0 = `{
|
||||
"d": {
|
||||
"results": []
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetResults1 = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='HT-6111.JPG')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='HT-6111.JPG')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_RESULTSType",
|
||||
"content_type": "image/jpeg",
|
||||
"media_src": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='HT-6111.JPG')/$value"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"name": "HT-6111.JPG",
|
||||
"additional_info": "",
|
||||
"mimetype": "image/jpeg"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='2times_hello')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='2times_hello')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_RESULTSType",
|
||||
"content_type": "text/plain",
|
||||
"media_src": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='2times_hello')/$value"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"name": "SAR_XML",
|
||||
"additional_info": "/usr/sap/trans/tmp/SAPK-001AAINITAPC1.SAR",
|
||||
"mimetype": "application/octet-stream"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetValues = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='PHASE')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='PHASE')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_VALUESType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"value_id": "PHASE",
|
||||
"value": "test1"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='PACKAGES')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='PACKAGES')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_VALUESType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"value_id": "PACKAGES",
|
||||
"value": "/BUILD/CORE"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='season')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='season')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_VALUESType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"value_id": "season",
|
||||
"value": "winter"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='SUN')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='SUN')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_VALUESType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"value_id": "SUN",
|
||||
"value": "FLOWER"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
375
pkg/abap/build/bfw.go
Normal file
375
pkg/abap/build/bfw.go
Normal file
@ -0,0 +1,375 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
)
|
||||
|
||||
// RunState : Current Status of the Build
|
||||
type RunState string
|
||||
type resultState string
|
||||
type msgty string
|
||||
|
||||
const (
|
||||
successful resultState = "SUCCESSFUL"
|
||||
warning resultState = "WARNING"
|
||||
erroneous resultState = "ERRONEOUS"
|
||||
aborted resultState = "ABORTED"
|
||||
// Initializing : Build Framework prepared
|
||||
Initializing RunState = "INITIALIZING"
|
||||
// Accepted : Build Framework triggered
|
||||
Accepted RunState = "ACCEPTED"
|
||||
// Running : Build Framework performs build
|
||||
Running RunState = "RUNNING"
|
||||
// Finished : Build Framework ended successful
|
||||
Finished RunState = "FINISHED"
|
||||
// Failed : Build Framework endded with error
|
||||
Failed RunState = "FAILED"
|
||||
loginfo msgty = "I"
|
||||
logwarning msgty = "W"
|
||||
logerror msgty = "E"
|
||||
logaborted msgty = "A"
|
||||
)
|
||||
|
||||
//******** structs needed for json convertion ********
|
||||
|
||||
type jsonBuild struct {
|
||||
Build *Build `json:"d"`
|
||||
}
|
||||
|
||||
type jsonTasks struct {
|
||||
ResultTasks struct {
|
||||
Tasks []task `json:"results"`
|
||||
} `json:"d"`
|
||||
}
|
||||
|
||||
type jsonLogs struct {
|
||||
ResultLogs struct {
|
||||
Logs []logStruct `json:"results"`
|
||||
} `json:"d"`
|
||||
}
|
||||
|
||||
type jsonResults struct {
|
||||
ResultResults struct {
|
||||
Results []Result `json:"results"`
|
||||
} `json:"d"`
|
||||
}
|
||||
|
||||
type jsonValues struct {
|
||||
ResultValues struct {
|
||||
Values []Value `json:"results"`
|
||||
} `json:"d"`
|
||||
}
|
||||
|
||||
// ******** resembling data model in backend ********
|
||||
|
||||
// Build : Information for all data comming from Build Framework
|
||||
type Build struct {
|
||||
Connector Connector
|
||||
BuildID string `json:"build_id"`
|
||||
RunState RunState `json:"run_state"`
|
||||
ResultState resultState `json:"result_state"`
|
||||
Phase string `json:"phase"`
|
||||
Entitytype string `json:"entitytype"`
|
||||
Startedby string `json:"startedby"`
|
||||
StartedAt string `json:"started_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
Tasks []task
|
||||
Values []Value
|
||||
}
|
||||
|
||||
type task struct {
|
||||
connector Connector
|
||||
BuildID string `json:"build_id"`
|
||||
TaskID int `json:"task_id"`
|
||||
LogID string `json:"log_id"`
|
||||
PluginClass string `json:"plugin_class"`
|
||||
StartedAt string `json:"started_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
ResultState resultState `json:"result_state"`
|
||||
Logs []logStruct
|
||||
Results []Result
|
||||
}
|
||||
|
||||
type logStruct struct {
|
||||
BuildID string `json:"build_id"`
|
||||
TaskID int `json:"task_id"`
|
||||
LogID string `json:"log_id"`
|
||||
Msgty msgty `json:"msgty"`
|
||||
Detlevel string `json:"detlevel"`
|
||||
Logline string `json:"log_line"`
|
||||
Timestamp string `json:"TIME_STMP"`
|
||||
}
|
||||
|
||||
// Result : Artefact from Build Framework step
|
||||
type Result struct {
|
||||
connector Connector
|
||||
BuildID string `json:"build_id"`
|
||||
TaskID int `json:"task_id"`
|
||||
Name string `json:"name"`
|
||||
AdditionalInfo string `json:"additional_info"`
|
||||
Mimetype string `json:"mimetype"`
|
||||
}
|
||||
|
||||
// Value : Returns Build Runtime Value
|
||||
type Value struct {
|
||||
connector Connector
|
||||
BuildID string `json:"build_id"`
|
||||
ValueID string `json:"value_id"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// Values : Returns Build Runtime Values
|
||||
type Values struct {
|
||||
Values []Value `json:"results"`
|
||||
}
|
||||
|
||||
type inputForPost struct {
|
||||
phase string
|
||||
values Values
|
||||
}
|
||||
|
||||
// *********************************************************************
|
||||
// ******************************* Funcs *******************************
|
||||
// *********************************************************************
|
||||
|
||||
// Start : Starts the Build Framework
|
||||
func (b *Build) Start(phase string, inputValues Values) error {
|
||||
if err := b.Connector.GetToken(""); err != nil {
|
||||
return err
|
||||
}
|
||||
importBody := inputForPost{
|
||||
phase: phase,
|
||||
values: inputValues,
|
||||
}.String()
|
||||
|
||||
body, err := b.Connector.Post("/builds", importBody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var jBuild jsonBuild
|
||||
json.Unmarshal(body, &jBuild)
|
||||
b.BuildID = jBuild.Build.BuildID
|
||||
b.RunState = jBuild.Build.RunState
|
||||
b.ResultState = jBuild.Build.ResultState
|
||||
b.Phase = jBuild.Build.Phase
|
||||
b.Entitytype = jBuild.Build.Entitytype
|
||||
b.Startedby = jBuild.Build.Startedby
|
||||
b.StartedAt = jBuild.Build.StartedAt
|
||||
b.FinishedAt = jBuild.Build.FinishedAt
|
||||
fmt.Println("Hello")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get : Get all Build tasks
|
||||
func (b *Build) Get() error {
|
||||
appendum := "/builds('" + b.BuildID + "')"
|
||||
body, err := b.Connector.Get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jBuild jsonBuild
|
||||
json.Unmarshal(body, &jBuild)
|
||||
b.RunState = jBuild.Build.RunState
|
||||
b.ResultState = jBuild.Build.ResultState
|
||||
b.Phase = jBuild.Build.Phase
|
||||
b.Entitytype = jBuild.Build.Entitytype
|
||||
b.Startedby = jBuild.Build.Startedby
|
||||
b.StartedAt = jBuild.Build.StartedAt
|
||||
b.FinishedAt = jBuild.Build.FinishedAt
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Build) getTasks() error {
|
||||
if len(b.Tasks) == 0 {
|
||||
appendum := "/builds('" + b.BuildID + "')/tasks"
|
||||
body, err := b.Connector.Get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jTasks jsonTasks
|
||||
json.Unmarshal(body, &jTasks)
|
||||
b.Tasks = jTasks.ResultTasks.Tasks
|
||||
sort.Slice(b.Tasks, func(i, j int) bool {
|
||||
return b.Tasks[i].TaskID < b.Tasks[j].TaskID
|
||||
})
|
||||
for i := range b.Tasks {
|
||||
b.Tasks[i].connector = b.Connector
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Build) getValues() error {
|
||||
if len(b.Values) == 0 {
|
||||
appendum := "/builds('" + b.BuildID + "')/values"
|
||||
body, err := b.Connector.Get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jValues jsonValues
|
||||
json.Unmarshal(body, &jValues)
|
||||
b.Values = jValues.ResultValues.Values
|
||||
for i := range b.Values {
|
||||
b.Values[i].connector = b.Connector
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Build) getLogs() error {
|
||||
if err := b.getTasks(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range b.Tasks {
|
||||
if err := b.Tasks[i].getLogs(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrintLogs : Returns the Build logs
|
||||
func (b *Build) PrintLogs() error {
|
||||
if err := b.getTasks(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range b.Tasks {
|
||||
if err := b.Tasks[i].printLogs(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Build) getResults() error {
|
||||
if err := b.getTasks(); err != nil {
|
||||
return err
|
||||
}
|
||||
for i := range b.Tasks {
|
||||
if err := b.Tasks[i].getResults(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *task) printLogs() error {
|
||||
if err := t.getLogs(); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, logs := range t.Logs {
|
||||
logs.print()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetResult : Returns the last Build artefact created from build step
|
||||
func (b *Build) GetResult(name string) (Result, error) {
|
||||
var Results []Result
|
||||
var returnResult Result
|
||||
if err := b.getResults(); err != nil {
|
||||
return returnResult, err
|
||||
}
|
||||
for _, task := range b.Tasks {
|
||||
for _, result := range task.Results {
|
||||
if result.Name == name {
|
||||
Results = append(Results, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
switch len(Results) {
|
||||
case 0:
|
||||
return returnResult, errors.New("No result named " + name + " was found")
|
||||
case 1:
|
||||
return Results[0], nil
|
||||
default:
|
||||
return returnResult, errors.New("More than one result with the name " + name + " was found")
|
||||
}
|
||||
}
|
||||
|
||||
// IsFinished : Returns Build run state
|
||||
func (b *Build) IsFinished() bool {
|
||||
if b.RunState == Finished || b.RunState == Failed {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (t *task) getLogs() error {
|
||||
if len(t.Logs) == 0 {
|
||||
appendum := fmt.Sprint("/tasks(build_id='", t.BuildID, "',task_id=", t.TaskID, ")/logs")
|
||||
body, err := t.connector.Get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jLogs jsonLogs
|
||||
json.Unmarshal(body, &jLogs)
|
||||
t.Logs = jLogs.ResultLogs.Logs
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *task) getResults() error {
|
||||
if len(t.Results) == 0 {
|
||||
appendum := fmt.Sprint("/tasks(build_id='", t.BuildID, "',task_id=", t.TaskID, ")/results")
|
||||
body, err := t.connector.Get(appendum)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var jResults jsonResults
|
||||
json.Unmarshal(body, &jResults)
|
||||
t.Results = jResults.ResultResults.Results
|
||||
for i := range t.Results {
|
||||
t.Results[i].connector = t.connector
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Download : Provides the atrefact of build step
|
||||
func (result *Result) Download(downloadPath string) error {
|
||||
appendum := fmt.Sprint("/results(build_id='", result.BuildID, "',task_id=", result.TaskID, ",name='", result.Name, "')/$value")
|
||||
err := result.connector.Download(appendum, downloadPath)
|
||||
return err
|
||||
}
|
||||
|
||||
func (logging *logStruct) print() {
|
||||
switch logging.Msgty {
|
||||
case loginfo:
|
||||
log.Entry().WithField("Timestamp", logging.Timestamp).Info(logging.Logline)
|
||||
case logwarning:
|
||||
log.Entry().WithField("Timestamp", logging.Timestamp).Warn(logging.Logline)
|
||||
case logerror:
|
||||
log.Entry().WithField("Timestamp", logging.Timestamp).Error(logging.Logline)
|
||||
case logaborted:
|
||||
log.Entry().WithField("Timestamp", logging.Timestamp).Error(logging.Logline)
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
// ******** parsing ********
|
||||
func (v Value) String() string {
|
||||
return fmt.Sprintf(
|
||||
`{ "value_id": "%s", "value": "%s" }`,
|
||||
v.ValueID,
|
||||
v.Value)
|
||||
}
|
||||
|
||||
func (vs Values) String() string {
|
||||
returnString := ""
|
||||
for _, value := range vs.Values {
|
||||
returnString = returnString + value.String() + ",\n"
|
||||
}
|
||||
returnString = returnString[:len(returnString)-2] //removes last ,
|
||||
return returnString
|
||||
}
|
||||
|
||||
func (in inputForPost) String() string {
|
||||
return fmt.Sprintf(`{ "phase": "%s", "values": [%s]}`, in.phase, in.values.String())
|
||||
}
|
345
pkg/abap/build/bfw_mock.go
Normal file
345
pkg/abap/build/bfw_mock.go
Normal file
@ -0,0 +1,345 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||
)
|
||||
|
||||
// DownloadClientMock : Mock for Download Client used for artefact test
|
||||
type DownloadClientMock struct{}
|
||||
|
||||
// DownloadFile : Empty file download
|
||||
func (dc *DownloadClientMock) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetOptions : Download Client options
|
||||
func (dc *DownloadClientMock) SetOptions(opts piperhttp.ClientOptions) {}
|
||||
|
||||
// ClMock : Mock for Build Framework Client used for BF test
|
||||
type ClMock struct {
|
||||
Token string
|
||||
StatusCode int
|
||||
Error error
|
||||
}
|
||||
|
||||
// SetOptions : BF Client options
|
||||
func (c *ClMock) SetOptions(opts piperhttp.ClientOptions) {}
|
||||
|
||||
// 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) {
|
||||
if method == "GET" || method == "POST" {
|
||||
var body []byte
|
||||
body = []byte(fakeResponse(method, url))
|
||||
return &http.Response{
|
||||
StatusCode: c.StatusCode,
|
||||
Body: ioutil.NopCloser(bytes.NewReader(body)),
|
||||
}, c.Error
|
||||
} else if method == "HEAD" {
|
||||
var body []byte
|
||||
header := http.Header{}
|
||||
header.Set("X-Csrf-Token", c.Token)
|
||||
body = []byte("")
|
||||
return &http.Response{
|
||||
StatusCode: c.StatusCode,
|
||||
Header: header,
|
||||
Body: ioutil.NopCloser(bytes.NewReader(body)),
|
||||
}, c.Error
|
||||
} else {
|
||||
return nil, c.Error
|
||||
}
|
||||
}
|
||||
|
||||
func fakeResponse(method string, url string) string {
|
||||
if method == "POST" {
|
||||
return responsePOST
|
||||
}
|
||||
if strings.HasSuffix(url, "/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')") {
|
||||
return responseGetBuild
|
||||
} else if strings.HasSuffix(url, "/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')/tasks") {
|
||||
return responseGetTasks
|
||||
} else if strings.HasSuffix(url, "/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)/logs") {
|
||||
return responseGetLog0
|
||||
} else if strings.HasSuffix(url, "/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)/logs") {
|
||||
return responseGetLog1
|
||||
} else if strings.HasSuffix(url, "/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')/values") {
|
||||
return responseGetValues
|
||||
} else if strings.HasSuffix(url, "tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)/results") {
|
||||
return responseGetResults0
|
||||
} else if strings.HasSuffix(url, "tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)/results") {
|
||||
return responseGetResults1
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
var responseGetBuild = `{
|
||||
"d": {
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_BUILDSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"run_state": "FINISHED",
|
||||
"result_state": "SUCCESSFUL",
|
||||
"phase": "test1",
|
||||
"entitytype": "P",
|
||||
"startedby": "BENTELER",
|
||||
"started_at": "/Date(1591718108103+0000)/",
|
||||
"finished_at": "/Date(1591718129432+0000)/",
|
||||
"tasks": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')/tasks"
|
||||
}
|
||||
},
|
||||
"values": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPOVMXK4DNPBDRW2M')/values"
|
||||
}
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
var responsePOST = `{
|
||||
"d": {
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPNVMOUQL2LHUFAUA')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPNVMOUQL2LHUFAUA')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_BUILDSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"run_state": "ACCEPTED",
|
||||
"result_state": "",
|
||||
"phase": "test1",
|
||||
"entitytype": "",
|
||||
"startedby": "BENTELER",
|
||||
"started_at": null,
|
||||
"finished_at": null,
|
||||
"tasks": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/builds('ABIFNLDCSQPNVMOUQL2LHUFAUA')/tasks"
|
||||
}
|
||||
},
|
||||
"values": {
|
||||
"results": []
|
||||
}
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetTasks = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_TASKSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_1",
|
||||
"plugin_class": "/BUILD/CL_TEST_PLUGIN_OK",
|
||||
"started_at": "/Date(1591718128730+0000)/",
|
||||
"finished_at": "/Date(1591718129369+0000)/",
|
||||
"result_state": "SUCCESSFUL",
|
||||
"logs": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)/logs"
|
||||
}
|
||||
},
|
||||
"results": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1)/results"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_TASKSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 0,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_0",
|
||||
"plugin_class": "",
|
||||
"started_at": "/Date(1591718128728+0000)/",
|
||||
"finished_at": "/Date(1591718129462+0000)/",
|
||||
"result_state": "SUCCESSFUL",
|
||||
"logs": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)/logs"
|
||||
}
|
||||
},
|
||||
"results": {
|
||||
"__deferred": {
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/tasks(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0)/results"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetLog0 = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_0')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_0')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_LOGSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 0,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_0",
|
||||
"msgty": "I",
|
||||
"detlevel": "3",
|
||||
"log_line": "I:/BUILD/LOG:000 ABAP Build Framework",
|
||||
"TIME_STMP": "20200721133523"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_0')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=0,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_0')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_LOGSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 0,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_0",
|
||||
"msgty": "I",
|
||||
"detlevel": "3",
|
||||
"log_line": "I:/BUILD/LOG:000 ... Build Execution finished SUCCESSFUL",
|
||||
"TIME_STMP": "20200721133528"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetLog1 = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_1')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_1')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_LOGSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_1",
|
||||
"msgty": "I",
|
||||
"detlevel": "1",
|
||||
"log_line": "I:/BUILD/LOG:000 Hello Packages [1]: , /BUILD/CORE, here is your lovely test_ok plugin!",
|
||||
"TIME_STMP": "20200721133528"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_1')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/logs(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,log_id='ABIFNLDCSQPOVMXK4DNPBDRW2M_1')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_LOGSType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"log_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M_1",
|
||||
"msgty": "W",
|
||||
"detlevel": "3",
|
||||
"log_line": "W:/BUILD/LOG:000 We can even have warnings!",
|
||||
"TIME_STMP": "20200721133528"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetResults0 = `{
|
||||
"d": {
|
||||
"results": []
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetResults1 = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='HT-6111.JPG')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='HT-6111.JPG')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_RESULTSType",
|
||||
"content_type": "image/jpeg",
|
||||
"media_src": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='HT-6111.JPG')/$value"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"name": "HT-6111.JPG",
|
||||
"additional_info": "",
|
||||
"mimetype": "image/jpeg"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='2times_hello')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='2times_hello')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_RESULTSType",
|
||||
"content_type": "text/plain",
|
||||
"media_src": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/results(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',task_id=1,name='2times_hello')/$value"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"task_id": 1,
|
||||
"name": "SAR_XML",
|
||||
"additional_info": "/usr/sap/trans/tmp/SAPK-001AAINITAPC1.SAR",
|
||||
"mimetype": "application/octet-stream"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
||||
|
||||
var responseGetValues = `{
|
||||
"d": {
|
||||
"results": [
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='PHASE')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='PHASE')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_VALUESType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"value_id": "PHASE",
|
||||
"value": "test1"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='PACKAGES')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='PACKAGES')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_VALUESType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"value_id": "PACKAGES",
|
||||
"value": "/BUILD/CORE"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='season')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='season')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_VALUESType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"value_id": "season",
|
||||
"value": "winter"
|
||||
},
|
||||
{
|
||||
"__metadata": {
|
||||
"id": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='SUN')",
|
||||
"uri": "https://ldai3yi3.wdf.sap.corp:44334/sap/opu/odata/BUILD/CORE_SRV/values(build_id='ABIFNLDCSQPOVMXK4DNPBDRW2M',value_id='SUN')",
|
||||
"type": "BUILD.CORE_SRV.xBUILDxVIEW_VALUESType"
|
||||
},
|
||||
"build_id": "ABIFNLDCSQPOVMXK4DNPBDRW2M",
|
||||
"value_id": "SUN",
|
||||
"value": "FLOWER"
|
||||
}
|
||||
]
|
||||
}
|
||||
}`
|
115
pkg/abap/build/bfw_test.go
Normal file
115
pkg/abap/build/bfw_test.go
Normal file
@ -0,0 +1,115 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func testSetup(client piperhttp.Sender, buildID string) Build {
|
||||
conn := new(Connector)
|
||||
conn.Client = client
|
||||
conn.DownloadClient = &DownloadClientMock{}
|
||||
conn.Header = make(map[string][]string)
|
||||
b := Build{
|
||||
Connector: *conn,
|
||||
BuildID: buildID,
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func TestStart(t *testing.T) {
|
||||
t.Run("Run start", func(t *testing.T) {
|
||||
client := &ClMock{
|
||||
Token: "MyToken",
|
||||
}
|
||||
b := testSetup(client, "")
|
||||
inputValues := Values{
|
||||
Values: []Value{
|
||||
{
|
||||
ValueID: "PACKAGES",
|
||||
Value: "/BUILD/CORE",
|
||||
},
|
||||
{
|
||||
ValueID: "season",
|
||||
Value: "winter",
|
||||
},
|
||||
},
|
||||
}
|
||||
err := b.Start("test", inputValues)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, Accepted, b.RunState)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
t.Run("Run Get", func(t *testing.T) {
|
||||
b := testSetup(&ClMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
err := b.Get()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, Finished, b.RunState)
|
||||
assert.Equal(t, 0, len(b.Tasks))
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetTasks(t *testing.T) {
|
||||
t.Run("Run getTasks", func(t *testing.T) {
|
||||
b := testSetup(&ClMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
assert.Equal(t, 0, len(b.Tasks))
|
||||
err := b.getTasks()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, b.Tasks[0].TaskID, 0)
|
||||
assert.Equal(t, b.Tasks[0].PluginClass, "")
|
||||
assert.Equal(t, b.Tasks[1].TaskID, 1)
|
||||
assert.Equal(t, b.Tasks[1].PluginClass, "/BUILD/CL_TEST_PLUGIN_OK")
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetLogs(t *testing.T) {
|
||||
t.Run("Run getLogs", func(t *testing.T) {
|
||||
b := testSetup(&ClMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
err := b.getLogs()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "I:/BUILD/LOG:000 ABAP Build Framework", b.Tasks[0].Logs[0].Logline)
|
||||
assert.Equal(t, loginfo, b.Tasks[0].Logs[0].Msgty)
|
||||
assert.Equal(t, "W:/BUILD/LOG:000 We can even have warnings!", b.Tasks[1].Logs[1].Logline)
|
||||
assert.Equal(t, logwarning, b.Tasks[1].Logs[1].Msgty)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetValues(t *testing.T) {
|
||||
t.Run("Run getValues", func(t *testing.T) {
|
||||
b := testSetup(&ClMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
assert.Equal(t, 0, len(b.Values))
|
||||
err := b.getValues()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 4, len(b.Values))
|
||||
assert.Equal(t, "PHASE", b.Values[0].ValueID)
|
||||
assert.Equal(t, "test1", b.Values[0].Value)
|
||||
assert.Equal(t, "PACKAGES", b.Values[1].ValueID)
|
||||
assert.Equal(t, "/BUILD/CORE", b.Values[1].Value)
|
||||
assert.Equal(t, "season", b.Values[2].ValueID)
|
||||
assert.Equal(t, "winter", b.Values[2].Value)
|
||||
assert.Equal(t, "SUN", b.Values[3].ValueID)
|
||||
assert.Equal(t, "FLOWER", b.Values[3].Value)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetResults(t *testing.T) {
|
||||
t.Run("Run getResults", func(t *testing.T) {
|
||||
b := testSetup(&ClMock{}, "ABIFNLDCSQPOVMXK4DNPBDRW2M")
|
||||
err := b.getResults()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 0, len(b.Tasks[0].Results))
|
||||
assert.Equal(t, 2, len(b.Tasks[1].Results))
|
||||
assert.Equal(t, "image/jpeg", b.Tasks[1].Results[0].Mimetype)
|
||||
assert.Equal(t, "application/octet-stream", b.Tasks[1].Results[1].Mimetype)
|
||||
|
||||
_, err = b.GetResult("does_not_exist")
|
||||
assert.Error(t, err)
|
||||
r, err := b.GetResult("SAR_XML")
|
||||
assert.Equal(t, "application/octet-stream", r.Mimetype)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
@ -5,7 +5,9 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"time"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/abaputils"
|
||||
piperhttp "github.com/SAP/jenkins-library/pkg/http"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
@ -18,6 +20,20 @@ type Connector struct {
|
||||
Baseurl string
|
||||
}
|
||||
|
||||
// ConnectorConfiguration : Handover Structure for Connector Creation
|
||||
type ConnectorConfiguration struct {
|
||||
CfAPIEndpoint string
|
||||
CfOrg string
|
||||
CfSpace string
|
||||
CfServiceInstance string
|
||||
CfServiceKeyName string
|
||||
Host string
|
||||
Username string
|
||||
Password string
|
||||
AddonDescriptor string
|
||||
MaxRuntimeInMinutes int
|
||||
}
|
||||
|
||||
// ******** technical communication calls ********
|
||||
|
||||
// GetToken : Get the X-CRSF Token from ABAP Backend for later post
|
||||
@ -89,7 +105,7 @@ func (conn Connector) Download(appendum string, downloadPath string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// InitAAKaaS : initializie Connector for communication with AAKaaS backend
|
||||
// InitAAKaaS : initialize Connector for communication with AAKaaS backend
|
||||
func (conn *Connector) InitAAKaaS(aAKaaSEndpoint string, username string, password string, inputclient piperhttp.Sender) {
|
||||
conn.Client = inputclient
|
||||
conn.Header = make(map[string][]string)
|
||||
@ -105,6 +121,47 @@ func (conn *Connector) InitAAKaaS(aAKaaSEndpoint string, username string, passwo
|
||||
conn.Baseurl = aAKaaSEndpoint
|
||||
}
|
||||
|
||||
// InitBuildFramework : initialize Connector for communication with ABAP SCP instance
|
||||
func (conn *Connector) InitBuildFramework(config ConnectorConfiguration, com abaputils.Communication, inputclient piperhttp.Sender) 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.SetOptions(piperhttp.ClientOptions{TransportTimeout: 20 * time.Second})
|
||||
// Mapping for options
|
||||
subOptions := abaputils.AbapEnvironmentOptions{}
|
||||
subOptions.CfAPIEndpoint = config.CfAPIEndpoint
|
||||
subOptions.CfServiceInstance = config.CfServiceInstance
|
||||
subOptions.CfServiceKeyName = config.CfServiceKeyName
|
||||
subOptions.CfOrg = config.CfOrg
|
||||
subOptions.CfSpace = config.CfSpace
|
||||
subOptions.Host = config.Host
|
||||
subOptions.Password = config.Password
|
||||
subOptions.Username = config.Username
|
||||
|
||||
// Determine the host, user and password, either via the input parameters or via a cloud foundry service key
|
||||
connectionDetails, err := com.GetAbapCommunicationArrangementInfo(subOptions, "/sap/opu/odata/BUILD/CORE_SRV")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Parameters for the ABAP Connection not available")
|
||||
}
|
||||
|
||||
conn.DownloadClient.SetOptions(piperhttp.ClientOptions{
|
||||
Username: connectionDetails.User,
|
||||
Password: connectionDetails.Password,
|
||||
})
|
||||
cookieJar, _ := cookiejar.New(nil)
|
||||
conn.Client.SetOptions(piperhttp.ClientOptions{
|
||||
Username: connectionDetails.User,
|
||||
Password: connectionDetails.Password,
|
||||
CookieJar: cookieJar,
|
||||
})
|
||||
conn.Baseurl = connectionDetails.URL
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UploadSarFile : upload *.sar file
|
||||
func (conn Connector) UploadSarFile(appendum string, sarFile []byte) error {
|
||||
url := conn.Baseurl + appendum
|
||||
|
Loading…
x
Reference in New Issue
Block a user