You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	Abap refactoring (#3340)
* Update abapAddonAssemblyKitReleasePackages.go * add error handling for initAAKaaS * runtime to config, url.QueryEscape, check return body * Update abapAddonAssemblyKitCheckCVs_test.go * add log entrys for testing * correct yaml * change unmarshal logic * Update abapAddonAssemblyKitCheckPV_test.go * adding utils functionality * Update bfw_test.go * reset CheckPV * reset CheckCVs * reset ReserveNextPackages * set back CheckPV and CheckCVs * moving mock * renaming * renaming * moving mocking to checkCVs test * fixing unittests * trying mock with comment * referencing unittest to mockfile * Update abapAddonAssemblyKitCheckCVs.go * Update cmd/abapAddonAssemblyKitCheckPV.go Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * Update cmd/abapAddonAssemblyKitReleasePackages.go Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * Update cmd/abapAddonAssemblyKitPublishTargetVector.go Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * Update cmd/abapAddonAssemblyKitReserveNextPackages.go Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * fixing unittests * fixing mock comment Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com>
This commit is contained in:
		| @@ -3,39 +3,31 @@ package cmd | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"net/url" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abap/aakaas" | ||||
| 	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" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func abapAddonAssemblyKitCheckCVs(config abapAddonAssemblyKitCheckCVsOptions, telemetryData *telemetry.CustomData, cpe *abapAddonAssemblyKitCheckCVsCommonPipelineEnvironment) { | ||||
| 	// for command execution use Command | ||||
| 	c := command.Command{} | ||||
| 	// reroute command output to logging framework | ||||
| 	c.Stdout(log.Writer()) | ||||
| 	c.Stderr(log.Writer()) | ||||
|  | ||||
| 	client := piperhttp.Client{} | ||||
|  | ||||
| 	// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end | ||||
| 	err := runAbapAddonAssemblyKitCheckCVs(&config, telemetryData, &client, cpe, abaputils.ReadAddonDescriptor) | ||||
| 	if err != nil { | ||||
| 	utils := aakaas.NewAakBundle() | ||||
| 	if err := runAbapAddonAssemblyKitCheckCVs(&config, telemetryData, &utils, cpe); err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runAbapAddonAssemblyKitCheckCVs(config *abapAddonAssemblyKitCheckCVsOptions, telemetryData *telemetry.CustomData, client piperhttp.Sender, | ||||
| 	cpe *abapAddonAssemblyKitCheckCVsCommonPipelineEnvironment, readAdoDescriptor abaputils.ReadAddonDescriptorType) error { | ||||
|  | ||||
| func runAbapAddonAssemblyKitCheckCVs(config *abapAddonAssemblyKitCheckCVsOptions, telemetryData *telemetry.CustomData, utils *aakaas.AakUtils, cpe *abapAddonAssemblyKitCheckCVsCommonPipelineEnvironment) error { | ||||
| 	conn := new(abapbuild.Connector) | ||||
| 	conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, client) | ||||
| 	if err := conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, *utils); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	log.Entry().Infof("Reading Product Version Information from addonDescriptor (aka addon.yml) file: %s", config.AddonDescriptorFileName) | ||||
| 	addonDescriptor, err := readAdoDescriptor(config.AddonDescriptorFileName) | ||||
| 	addonDescriptor, err := (*utils).ReadAddonDescriptor(config.AddonDescriptorFileName) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -87,13 +79,15 @@ func (c *componentVersion) copyFieldsToRepo(initialRepo *abaputils.Repository) { | ||||
|  | ||||
| func (c *componentVersion) validate() error { | ||||
| 	log.Entry().Infof("Validate component %s version %s and resolve version", c.Name, c.VersionYAML) | ||||
| 	appendum := "/odata/aas_ocs_package/ValidateComponentVersion?Name='" + c.Name + "'&Version='" + c.VersionYAML + "'" | ||||
| 	appendum := "/odata/aas_ocs_package/ValidateComponentVersion?Name='" + url.QueryEscape(c.Name) + "'&Version='" + url.QueryEscape(c.VersionYAML) + "'" | ||||
| 	body, err := c.Connector.Get(appendum) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	var jCV jsonComponentVersion | ||||
| 	json.Unmarshal(body, &jCV) | ||||
| 	if err := json.Unmarshal(body, &jCV); err != nil { | ||||
| 		return errors.Wrap(err, "Unexpected AAKaaS response for Validate Component Version: "+string(body)) | ||||
| 	} | ||||
| 	c.Name = jCV.ComponentVersion.Name | ||||
| 	c.Version = jCV.ComponentVersion.Version | ||||
| 	c.SpLevel = jCV.ComponentVersion.SpLevel | ||||
|   | ||||
| @@ -4,60 +4,24 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abap/aakaas" | ||||
| 	abapbuild "github.com/SAP/jenkins-library/pkg/abap/build" | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func mockReadAddonDescriptor(FileName string) (abaputils.AddonDescriptor, error) { | ||||
| 	var addonDescriptor abaputils.AddonDescriptor | ||||
| 	var err error | ||||
| 	switch FileName { | ||||
| 	case "success": | ||||
| 		{ | ||||
| 			addonDescriptor = abaputils.AddonDescriptor{ | ||||
| 				AddonProduct:     "/DRNMSPC/PRD01", | ||||
| 				AddonVersionYAML: "3.2.1", | ||||
| 				Repositories: []abaputils.Repository{ | ||||
| 					{ | ||||
| 						Name:        "/DRNMSPC/COMP01", | ||||
| 						VersionYAML: "1.2.3", | ||||
| 						CommitID:    "HUGO1234", | ||||
| 					}, | ||||
| 				}, | ||||
| 			} | ||||
| 		} | ||||
| 	case "noCommitID": | ||||
| 		{ | ||||
| 			addonDescriptor = abaputils.AddonDescriptor{ | ||||
| 				AddonProduct:     "/DRNMSPC/PRD01", | ||||
| 				AddonVersionYAML: "3.2.1", | ||||
| 				Repositories: []abaputils.Repository{ | ||||
| 					{ | ||||
| 						Name:        "/DRNMSPC/COMP01", | ||||
| 						VersionYAML: "1.2.3", | ||||
| 					}, | ||||
| 				}, | ||||
| 			} | ||||
| 		} | ||||
| 	case "failing": | ||||
| 		{ | ||||
| 			err = errors.New("error in ReadAddonDescriptor") | ||||
| 		} | ||||
| 	} | ||||
| 	return addonDescriptor, err | ||||
| } | ||||
|  | ||||
| func TestCheckCVsStep(t *testing.T) { | ||||
| 	var config abapAddonAssemblyKitCheckCVsOptions | ||||
| 	var cpe abapAddonAssemblyKitCheckCVsCommonPipelineEnvironment | ||||
| 	client := &abaputils.ClientMock{ | ||||
| 		Body: responseCheckCVs, | ||||
| 	} | ||||
| 	bundle := aakaas.NewAakBundleMock() | ||||
| 	bundle.SetBody(responseCheckCVs) | ||||
| 	utils := bundle.GetUtils() | ||||
| 	config.Username = "dummyUser" | ||||
| 	config.Password = "dummyPassword" | ||||
| 	t.Run("step success", func(t *testing.T) { | ||||
| 		config.AddonDescriptorFileName = "success" | ||||
| 		err := runAbapAddonAssemblyKitCheckCVs(&config, nil, client, &cpe, mockReadAddonDescriptor) | ||||
| 		err := runAbapAddonAssemblyKitCheckCVs(&config, nil, &utils, &cpe) | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		var addonDescriptorFinal abaputils.AddonDescriptor | ||||
| 		json.Unmarshal([]byte(cpe.abap.addonDescriptor), &addonDescriptorFinal) | ||||
| @@ -68,23 +32,21 @@ func TestCheckCVsStep(t *testing.T) { | ||||
| 	}) | ||||
| 	t.Run("step error - in validate(no CommitID)", func(t *testing.T) { | ||||
| 		config.AddonDescriptorFileName = "noCommitID" | ||||
| 		err := runAbapAddonAssemblyKitCheckCVs(&config, nil, client, &cpe, mockReadAddonDescriptor) | ||||
| 		err := runAbapAddonAssemblyKitCheckCVs(&config, nil, &utils, &cpe) | ||||
| 		assert.Error(t, err, "Must end with error") | ||||
| 		assert.Contains(t, err.Error(), "CommitID missing in repo") | ||||
| 	}) | ||||
| 	t.Run("step error - in ReadAddonDescriptor", func(t *testing.T) { | ||||
| 		config.AddonDescriptorFileName = "failing" | ||||
| 		err := runAbapAddonAssemblyKitCheckCVs(&config, nil, client, &cpe, mockReadAddonDescriptor) | ||||
| 		err := runAbapAddonAssemblyKitCheckCVs(&config, nil, &utils, &cpe) | ||||
| 		assert.Error(t, err, "Must end with error") | ||||
| 		assert.Contains(t, "error in ReadAddonDescriptor", err.Error()) | ||||
| 	}) | ||||
| 	t.Run("step error - in validate", func(t *testing.T) { | ||||
| 		config.AddonDescriptorFileName = "success" | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			Body:  "ErrorBody", | ||||
| 			Error: errors.New("error during validation"), | ||||
| 		} | ||||
| 		err := runAbapAddonAssemblyKitCheckCVs(&config, nil, client, &cpe, mockReadAddonDescriptor) | ||||
| 		bundle.SetBody("ErrorBody") | ||||
| 		bundle.SetError("error during validation") | ||||
| 		err := runAbapAddonAssemblyKitCheckCVs(&config, nil, &utils, &cpe) | ||||
| 		assert.Error(t, err, "Must end with error") | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -4,39 +4,31 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"net/url" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abap/aakaas" | ||||
| 	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" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func abapAddonAssemblyKitCheckPV(config abapAddonAssemblyKitCheckPVOptions, telemetryData *telemetry.CustomData, cpe *abapAddonAssemblyKitCheckPVCommonPipelineEnvironment) { | ||||
| 	// for command execution use Command | ||||
| 	c := command.Command{} | ||||
| 	// reroute command output to logging framework | ||||
| 	c.Stdout(log.Writer()) | ||||
| 	c.Stderr(log.Writer()) | ||||
|  | ||||
| 	client := piperhttp.Client{} | ||||
|  | ||||
| 	utils := aakaas.NewAakBundle() | ||||
| 	// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end | ||||
| 	err := runAbapAddonAssemblyKitCheckPV(&config, telemetryData, &client, cpe, abaputils.ReadAddonDescriptor) | ||||
| 	if err != nil { | ||||
| 	if err := runAbapAddonAssemblyKitCheckPV(&config, telemetryData, &utils, cpe); err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runAbapAddonAssemblyKitCheckPV(config *abapAddonAssemblyKitCheckPVOptions, telemetryData *telemetry.CustomData, client piperhttp.Sender, | ||||
| 	cpe *abapAddonAssemblyKitCheckPVCommonPipelineEnvironment, readAdoDescriptor abaputils.ReadAddonDescriptorType) error { | ||||
| func runAbapAddonAssemblyKitCheckPV(config *abapAddonAssemblyKitCheckPVOptions, telemetryData *telemetry.CustomData, utils *aakaas.AakUtils, cpe *abapAddonAssemblyKitCheckPVCommonPipelineEnvironment) error { | ||||
|  | ||||
| 	conn := new(abapbuild.Connector) | ||||
| 	conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, client) | ||||
| 	if err := conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, *utils); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	log.Entry().Infof("Reading Product Version Information from addonDescriptor (aka addon.yml) file: %s", config.AddonDescriptorFileName) | ||||
| 	addonDescriptor, err := readAdoDescriptor(config.AddonDescriptorFileName) | ||||
| 	addonDescriptor, err := (*utils).ReadAddonDescriptor(config.AddonDescriptorFileName) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -93,7 +85,9 @@ func (p *productVersion) validateAndResolveVersionFields() error { | ||||
| 		return err | ||||
| 	} | ||||
| 	var jPV jsonProductVersion | ||||
| 	json.Unmarshal(body, &jPV) | ||||
| 	if err := json.Unmarshal(body, &jPV); err != nil { | ||||
| 		return errors.Wrap(err, "Unexpected AAKaaS response for Validate Product Version: "+string(body)) | ||||
| 	} | ||||
| 	p.Name = jPV.ProductVersion.Name | ||||
| 	p.Version = jPV.ProductVersion.Version | ||||
| 	p.SpsLevel = jPV.ProductVersion.SpsLevel | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abap/aakaas" | ||||
| 	abapbuild "github.com/SAP/jenkins-library/pkg/abap/build" | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/pkg/errors" | ||||
| @@ -13,12 +14,14 @@ import ( | ||||
| func TestCheckPVStep(t *testing.T) { | ||||
| 	var config abapAddonAssemblyKitCheckPVOptions | ||||
| 	var cpe abapAddonAssemblyKitCheckPVCommonPipelineEnvironment | ||||
| 	client := &abaputils.ClientMock{ | ||||
| 		Body: responseCheckPV, | ||||
| 	} | ||||
| 	bundle := aakaas.NewAakBundleMock() | ||||
| 	bundle.SetBody(responseCheckPV) | ||||
| 	utils := bundle.GetUtils() | ||||
| 	config.Username = "dummyUser" | ||||
| 	config.Password = "dummyPassword" | ||||
| 	t.Run("step success", func(t *testing.T) { | ||||
| 		config.AddonDescriptorFileName = "success" | ||||
| 		err := runAbapAddonAssemblyKitCheckPV(&config, nil, client, &cpe, mockReadAddonDescriptor) | ||||
| 		err := runAbapAddonAssemblyKitCheckPV(&config, nil, &utils, &cpe) | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		var addonDescriptorFinal abaputils.AddonDescriptor | ||||
| 		json.Unmarshal([]byte(cpe.abap.addonDescriptor), &addonDescriptorFinal) | ||||
| @@ -28,17 +31,15 @@ func TestCheckPVStep(t *testing.T) { | ||||
| 	}) | ||||
| 	t.Run("step error - in ReadAddonDescriptor", func(t *testing.T) { | ||||
| 		config.AddonDescriptorFileName = "failing" | ||||
| 		err := runAbapAddonAssemblyKitCheckPV(&config, nil, client, &cpe, mockReadAddonDescriptor) | ||||
| 		err := runAbapAddonAssemblyKitCheckPV(&config, nil, &utils, &cpe) | ||||
| 		assert.Error(t, err, "Did expect error") | ||||
| 		assert.Equal(t, err.Error(), "error in ReadAddonDescriptor") | ||||
| 	}) | ||||
| 	t.Run("step error - in validate", func(t *testing.T) { | ||||
| 		config.AddonDescriptorFileName = "success" | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			Body:  "ErrorBody", | ||||
| 			Error: errors.New("error during validation"), | ||||
| 		} | ||||
| 		err := runAbapAddonAssemblyKitCheckPV(&config, nil, client, &cpe, mockReadAddonDescriptor) | ||||
| 		bundle.SetBody("ErrorBody") | ||||
| 		bundle.SetError("error during validation") | ||||
| 		err := runAbapAddonAssemblyKitCheckPV(&config, nil, &utils, &cpe) | ||||
| 		assert.Error(t, err, "Did expect error") | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -6,38 +6,28 @@ import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/abap/aakaas" | ||||
| 	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" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func abapAddonAssemblyKitPublishTargetVector(config abapAddonAssemblyKitPublishTargetVectorOptions, telemetryData *telemetry.CustomData) { | ||||
| 	// for command execution use Command | ||||
| 	c := command.Command{} | ||||
| 	// reroute command output to logging framework | ||||
| 	c.Stdout(log.Writer()) | ||||
| 	c.Stderr(log.Writer()) | ||||
|  | ||||
| 	client := piperhttp.Client{} | ||||
| 	utils := aakaas.NewAakBundleWithTime(time.Duration(config.MaxRuntimeInMinutes), time.Duration(config.PollingIntervalInSeconds)) | ||||
|  | ||||
| 	// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end | ||||
| 	err := runAbapAddonAssemblyKitPublishTargetVector(&config, telemetryData, &client, time.Duration(config.MaxRuntimeInMinutes)*time.Minute, time.Duration(config.PollingIntervalInSeconds)*time.Second) | ||||
| 	if err != nil { | ||||
| 	if err := runAbapAddonAssemblyKitPublishTargetVector(&config, telemetryData, &utils); err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runAbapAddonAssemblyKitPublishTargetVector(config *abapAddonAssemblyKitPublishTargetVectorOptions, telemetryData *telemetry.CustomData, client piperhttp.Sender, | ||||
| 	maxRuntime time.Duration, pollingInterval time.Duration) error { | ||||
| func runAbapAddonAssemblyKitPublishTargetVector(config *abapAddonAssemblyKitPublishTargetVectorOptions, telemetryData *telemetry.CustomData, utils *aakaas.AakUtils) error { | ||||
|  | ||||
| 	conn := new(abapbuild.Connector) | ||||
| 	if err := conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, client); err != nil { | ||||
| 	if err := conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, *utils); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	conn.MaxRuntime = maxRuntime | ||||
| 	conn.PollingInterval = pollingInterval | ||||
| 	conn.MaxRuntime = (*utils).GetMaxRuntime() | ||||
| 	conn.PollingInterval = (*utils).GetPollingInterval() | ||||
|  | ||||
| 	addonDescriptor := new(abaputils.AddonDescriptor) | ||||
| 	if err := addonDescriptor.InitFromJSONstring(config.AddonDescriptor); err != nil { | ||||
|   | ||||
| @@ -3,12 +3,10 @@ package cmd | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abap/aakaas" | ||||
| 	abapbuild "github.com/SAP/jenkins-library/pkg/abap/build" | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| @@ -32,9 +30,11 @@ func TestPublishTargetVectorStep(t *testing.T) { | ||||
| 		mc.AddData(aakaas.AAKaaSTVPublishProdPost) | ||||
| 		mc.AddData(aakaas.AAKaaSGetTVPublishRunning) | ||||
| 		mc.AddData(aakaas.AAKaaSGetTVPublishProdSuccess) | ||||
| 		bundle := aakaas.NewAakBundleMockNewMC(&mc) | ||||
| 		utils := bundle.GetUtils() | ||||
|  | ||||
| 		//act | ||||
| 		err := runAbapAddonAssemblyKitPublishTargetVector(&config, nil, &mc, time.Duration(1*time.Second), time.Duration(1*time.Microsecond)) | ||||
| 		err := runAbapAddonAssemblyKitPublishTargetVector(&config, nil, &utils) | ||||
| 		//assert | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 	}) | ||||
| @@ -47,20 +47,24 @@ func TestPublishTargetVectorStep(t *testing.T) { | ||||
| 		mc.AddData(aakaas.AAKaaSTVPublishTestPost) | ||||
| 		mc.AddData(aakaas.AAKaaSGetTVPublishRunning) | ||||
| 		mc.AddData(aakaas.AAKaaSGetTVPublishTestSuccess) | ||||
| 		bundle := aakaas.NewAakBundleMockNewMC(&mc) | ||||
| 		utils := bundle.GetUtils() | ||||
|  | ||||
| 		//act | ||||
| 		err := runAbapAddonAssemblyKitPublishTargetVector(&config, nil, &mc, time.Duration(1*time.Second), time.Duration(1*time.Microsecond)) | ||||
| 		err := runAbapAddonAssemblyKitPublishTargetVector(&config, nil, &utils) | ||||
| 		//assert | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("step fail http", func(t *testing.T) { | ||||
| 		//arrange | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			Body:  "dummy", | ||||
| 			Error: errors.New("dummy"), | ||||
| 		} | ||||
| 		bundle := aakaas.NewAakBundleMock() | ||||
| 		bundle.SetBody("dummy") | ||||
| 		bundle.SetError("dummy") | ||||
| 		utils := bundle.GetUtils() | ||||
|  | ||||
| 		//act | ||||
| 		err := runAbapAddonAssemblyKitPublishTargetVector(&config, nil, client, time.Duration(1*time.Second), time.Duration(1*time.Microsecond)) | ||||
| 		err := runAbapAddonAssemblyKitPublishTargetVector(&config, nil, &utils) | ||||
| 		//assert | ||||
| 		assert.Error(t, err, "Must end with error") | ||||
| 	}) | ||||
| @@ -69,8 +73,11 @@ func TestPublishTargetVectorStep(t *testing.T) { | ||||
| 		//arrange | ||||
| 		config := abapAddonAssemblyKitPublishTargetVectorOptions{} | ||||
| 		mc := abapbuild.NewMockClient() | ||||
| 		bundle := aakaas.NewAakBundleMockNewMC(&mc) | ||||
| 		utils := bundle.GetUtils() | ||||
|  | ||||
| 		//act | ||||
| 		err := runAbapAddonAssemblyKitPublishTargetVector(&config, nil, &mc, time.Duration(1*time.Second), time.Duration(1*time.Microsecond)) | ||||
| 		err := runAbapAddonAssemblyKitPublishTargetVector(&config, nil, &utils) | ||||
| 		//assert | ||||
| 		assert.Error(t, err, "Must end with error") | ||||
| 	}) | ||||
|   | ||||
| @@ -7,35 +7,26 @@ import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/abap/aakaas" | ||||
| 	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" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func abapAddonAssemblyKitReleasePackages(config abapAddonAssemblyKitReleasePackagesOptions, telemetryData *telemetry.CustomData, cpe *abapAddonAssemblyKitReleasePackagesCommonPipelineEnvironment) { | ||||
| 	// for command execution use Command | ||||
| 	c := command.Command{} | ||||
| 	// reroute command output to logging framework | ||||
| 	c.Stdout(log.Writer()) | ||||
| 	c.Stderr(log.Writer()) | ||||
| 	utils := aakaas.NewAakBundleWithTime(time.Duration(config.MaxRuntimeInMinutes), time.Duration(config.PollingIntervalInSeconds)) | ||||
|  | ||||
| 	client := piperhttp.Client{} | ||||
|  | ||||
| 	maxRuntimeInMinutes := time.Duration(5 * time.Minute) | ||||
| 	pollIntervalsInSeconds := time.Duration(30 * time.Second) | ||||
| 	// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end | ||||
| 	err := runAbapAddonAssemblyKitReleasePackages(&config, telemetryData, &client, cpe, maxRuntimeInMinutes, pollIntervalsInSeconds) | ||||
| 	if err != nil { | ||||
| 	if err := runAbapAddonAssemblyKitReleasePackages(&config, telemetryData, &utils, cpe); err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runAbapAddonAssemblyKitReleasePackages(config *abapAddonAssemblyKitReleasePackagesOptions, telemetryData *telemetry.CustomData, client piperhttp.Sender, | ||||
| 	cpe *abapAddonAssemblyKitReleasePackagesCommonPipelineEnvironment, maxRuntimeInMinutes time.Duration, pollIntervalsInSeconds time.Duration) error { | ||||
| func runAbapAddonAssemblyKitReleasePackages(config *abapAddonAssemblyKitReleasePackagesOptions, telemetryData *telemetry.CustomData, utils *aakaas.AakUtils, | ||||
| 	cpe *abapAddonAssemblyKitReleasePackagesCommonPipelineEnvironment) error { | ||||
| 	conn := new(abapbuild.Connector) | ||||
| 	conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, client) | ||||
| 	if err := conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, *utils); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	var addonDescriptor abaputils.AddonDescriptor | ||||
| 	json.Unmarshal([]byte(config.AddonDescriptor), &addonDescriptor) | ||||
|  | ||||
| @@ -44,14 +35,13 @@ func runAbapAddonAssemblyKitReleasePackages(config *abapAddonAssemblyKitReleaseP | ||||
| 		return err | ||||
| 	} | ||||
| 	packagesWithReposLocked, packagesWithReposNotLocked := sortByStatus(addonDescriptor.Repositories, *conn) | ||||
| 	packagesWithReposLocked, err = releaseAndPoll(packagesWithReposLocked, maxRuntimeInMinutes, pollIntervalsInSeconds) | ||||
| 	packagesWithReposLocked, err = releaseAndPoll(packagesWithReposLocked, utils) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	addonDescriptor.Repositories = sortingBack(packagesWithReposLocked, packagesWithReposNotLocked) | ||||
| 	log.Entry().Info("Writing package status to CommonPipelineEnvironment") | ||||
| 	backToCPE, _ := json.Marshal(addonDescriptor) | ||||
| 	cpe.abap.addonDescriptor = string(backToCPE) | ||||
| 	cpe.abap.addonDescriptor = string(addonDescriptor.AsJSON()) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| @@ -96,9 +86,9 @@ func sortByStatus(repos []abaputils.Repository, conn abapbuild.Connector) ([]aak | ||||
| 	return packagesWithReposLocked, packagesWithReposNotLocked | ||||
| } | ||||
|  | ||||
| func releaseAndPoll(pckgWR []aakaas.PackageWithRepository, maxRuntimeInMinutes time.Duration, pollIntervalsInSeconds time.Duration) ([]aakaas.PackageWithRepository, error) { | ||||
| 	timeout := time.After(maxRuntimeInMinutes) | ||||
| 	ticker := time.Tick(pollIntervalsInSeconds) | ||||
| func releaseAndPoll(pckgWR []aakaas.PackageWithRepository, utils *aakaas.AakUtils) ([]aakaas.PackageWithRepository, error) { | ||||
| 	timeout := time.After((*utils).GetMaxRuntime()) | ||||
| 	ticker := time.Tick((*utils).GetPollingInterval()) | ||||
|  | ||||
| 	for { | ||||
| 		select { | ||||
| @@ -111,7 +101,7 @@ func releaseAndPoll(pckgWR []aakaas.PackageWithRepository, maxRuntimeInMinutes t | ||||
| 					err := pckgWR[i].Package.Release() | ||||
| 					// if there is an error, release is not yet finished | ||||
| 					if err != nil { | ||||
| 						log.Entry().Infof("Release of %s is not yet finished, check again in %s", pckgWR[i].Package.PackageName, pollIntervalsInSeconds) | ||||
| 						log.Entry().Infof("Release of %s is not yet finished, check again in %s", pckgWR[i].Package.PackageName, (*utils).GetPollingInterval()) | ||||
| 						allFinished = false | ||||
| 					} | ||||
| 				} | ||||
|   | ||||
| @@ -22,6 +22,8 @@ type abapAddonAssemblyKitReleasePackagesOptions struct { | ||||
| 	Username                     string `json:"username,omitempty"` | ||||
| 	Password                     string `json:"password,omitempty"` | ||||
| 	AddonDescriptor              string `json:"addonDescriptor,omitempty"` | ||||
| 	MaxRuntimeInMinutes          int    `json:"maxRuntimeInMinutes,omitempty"` | ||||
| 	PollingIntervalInSeconds     int    `json:"pollingIntervalInSeconds,omitempty"` | ||||
| } | ||||
|  | ||||
| type abapAddonAssemblyKitReleasePackagesCommonPipelineEnvironment struct { | ||||
| @@ -150,6 +152,8 @@ func addAbapAddonAssemblyKitReleasePackagesFlags(cmd *cobra.Command, stepConfig | ||||
| 	cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "User for the Addon Assembly Kit as a Service (AAKaaS) system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Password for the Addon Assembly Kit as a Service (AAKaaS) system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.AddonDescriptor, "addonDescriptor", os.Getenv("PIPER_addonDescriptor"), "Structure in the commonPipelineEnvironment containing information about the Product Version and corresponding Software Component Versions") | ||||
| 	cmd.Flags().IntVar(&stepConfig.MaxRuntimeInMinutes, "maxRuntimeInMinutes", 5, "Maximum runtime for status polling in minutes") | ||||
| 	cmd.Flags().IntVar(&stepConfig.PollingIntervalInSeconds, "pollingIntervalInSeconds", 30, "Wait time in seconds between polling calls") | ||||
|  | ||||
| 	cmd.MarkFlagRequired("abapAddonAssemblyKitEndpoint") | ||||
| 	cmd.MarkFlagRequired("username") | ||||
| @@ -212,6 +216,24 @@ func abapAddonAssemblyKitReleasePackagesMetadata() config.StepData { | ||||
| 						Aliases:   []config.Alias{}, | ||||
| 						Default:   os.Getenv("PIPER_addonDescriptor"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "maxRuntimeInMinutes", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "int", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     5, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "pollingIntervalInSeconds", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "int", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     30, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			Outputs: config.StepOutputs{ | ||||
|   | ||||
| @@ -5,22 +5,22 @@ import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abap/aakaas" | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/pkg/errors" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestReleasePackagesStep(t *testing.T) { | ||||
| 	var config abapAddonAssemblyKitReleasePackagesOptions | ||||
| 	var cpe abapAddonAssemblyKitReleasePackagesCommonPipelineEnvironment | ||||
| 	client := &abaputils.ClientMock{ | ||||
| 		Body:       responseRelease, | ||||
| 		Token:      "myToken", | ||||
| 		StatusCode: 200, | ||||
| 	} | ||||
| 	timeout := time.Duration(5 * time.Second) | ||||
| 	pollInterval := time.Duration(1 * time.Second) | ||||
| 	bundle := aakaas.NewAakBundleMock() | ||||
| 	bundle.SetBody(responseRelease) | ||||
| 	utils := bundle.GetUtils() | ||||
|  | ||||
| 	config.Username = "dummyUser" | ||||
| 	config.Password = "dummyPassword" | ||||
| 	t.Run("step success", func(t *testing.T) { | ||||
| 		//arrange | ||||
| 		addonDescriptor := abaputils.AddonDescriptor{ | ||||
| 			Repositories: []abaputils.Repository{ | ||||
| 				{ | ||||
| @@ -35,9 +35,9 @@ func TestReleasePackagesStep(t *testing.T) { | ||||
| 		} | ||||
| 		adoDesc, _ := json.Marshal(addonDescriptor) | ||||
| 		config.AddonDescriptor = string(adoDesc) | ||||
|  | ||||
| 		err := runAbapAddonAssemblyKitReleasePackages(&config, nil, client, &cpe, timeout, pollInterval) | ||||
|  | ||||
| 		//act | ||||
| 		err := runAbapAddonAssemblyKitReleasePackages(&config, nil, &utils, &cpe) | ||||
| 		//assert | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		var addonDescriptorFinal abaputils.AddonDescriptor | ||||
| 		json.Unmarshal([]byte(cpe.abap.addonDescriptor), &addonDescriptorFinal) | ||||
| @@ -45,6 +45,7 @@ func TestReleasePackagesStep(t *testing.T) { | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("step error - invalid input", func(t *testing.T) { | ||||
| 		//arrange | ||||
| 		addonDescriptor := abaputils.AddonDescriptor{ | ||||
| 			Repositories: []abaputils.Repository{ | ||||
| 				{ | ||||
| @@ -54,14 +55,17 @@ func TestReleasePackagesStep(t *testing.T) { | ||||
| 		} | ||||
| 		adoDesc, _ := json.Marshal(addonDescriptor) | ||||
| 		config.AddonDescriptor = string(adoDesc) | ||||
|  | ||||
| 		err := runAbapAddonAssemblyKitReleasePackages(&config, nil, client, &cpe, timeout, pollInterval) | ||||
| 		//act | ||||
| 		err := runAbapAddonAssemblyKitReleasePackages(&config, nil, &utils, &cpe) | ||||
| 		//assert | ||||
| 		assert.Error(t, err, "Did expect error") | ||||
| 		assert.Equal(t, err.Error(), "Parameter missing. Please provide the name of the package which should be released") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("step error - timeout", func(t *testing.T) { | ||||
| 		client.Error = errors.New("Release not finished") | ||||
| 		//arrange | ||||
| 		bundle.SetError("Release not finished") | ||||
| 		bundle.SetMaxRuntime(1 * time.Microsecond) | ||||
| 		addonDescriptor := abaputils.AddonDescriptor{ | ||||
| 			Repositories: []abaputils.Repository{ | ||||
| 				{ | ||||
| @@ -72,9 +76,9 @@ func TestReleasePackagesStep(t *testing.T) { | ||||
| 		} | ||||
| 		adoDesc, _ := json.Marshal(addonDescriptor) | ||||
| 		config.AddonDescriptor = string(adoDesc) | ||||
|  | ||||
| 		timeout := time.Duration(2 * time.Second) | ||||
| 		err := runAbapAddonAssemblyKitReleasePackages(&config, nil, client, &cpe, timeout, pollInterval) | ||||
| 		//act | ||||
| 		err := runAbapAddonAssemblyKitReleasePackages(&config, nil, &utils, &cpe) | ||||
| 		//assert | ||||
| 		assert.Error(t, err, "Did expect error") | ||||
| 		assert.Equal(t, err.Error(), "Timed out") | ||||
| 	}) | ||||
|   | ||||
| @@ -7,35 +7,25 @@ import ( | ||||
| 	"github.com/SAP/jenkins-library/pkg/abap/aakaas" | ||||
| 	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" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| func abapAddonAssemblyKitReserveNextPackages(config abapAddonAssemblyKitReserveNextPackagesOptions, telemetryData *telemetry.CustomData, cpe *abapAddonAssemblyKitReserveNextPackagesCommonPipelineEnvironment) { | ||||
| 	// for command execution use Command | ||||
| 	c := command.Command{} | ||||
| 	// reroute command output to logging framework | ||||
| 	c.Stdout(log.Writer()) | ||||
| 	c.Stderr(log.Writer()) | ||||
|  | ||||
| 	client := piperhttp.Client{} | ||||
| 	maxRuntimeInMinutes := time.Duration(5 * time.Minute) | ||||
| 	pollIntervalsInSeconds := time.Duration(30 * time.Second) | ||||
| 	utils := aakaas.NewAakBundleWithTime(time.Duration(config.MaxRuntimeInMinutes), time.Duration(config.PollingIntervalInSeconds)) | ||||
| 	// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end | ||||
| 	err := runAbapAddonAssemblyKitReserveNextPackages(&config, telemetryData, &client, cpe, maxRuntimeInMinutes, pollIntervalsInSeconds) | ||||
| 	if err != nil { | ||||
| 	if err := runAbapAddonAssemblyKitReserveNextPackages(&config, telemetryData, &utils, cpe); err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runAbapAddonAssemblyKitReserveNextPackages(config *abapAddonAssemblyKitReserveNextPackagesOptions, telemetryData *telemetry.CustomData, client piperhttp.Sender, | ||||
| 	cpe *abapAddonAssemblyKitReserveNextPackagesCommonPipelineEnvironment, maxRuntimeInMinutes time.Duration, pollIntervalsInSeconds time.Duration) error { | ||||
| func runAbapAddonAssemblyKitReserveNextPackages(config *abapAddonAssemblyKitReserveNextPackagesOptions, telemetryData *telemetry.CustomData, utils *aakaas.AakUtils, | ||||
| 	cpe *abapAddonAssemblyKitReserveNextPackagesCommonPipelineEnvironment) error { | ||||
|  | ||||
| 	conn := new(abapbuild.Connector) | ||||
| 	if err := conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, client); err != nil { | ||||
| 	if err := conn.InitAAKaaS(config.AbapAddonAssemblyKitEndpoint, config.Username, config.Password, *utils); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -49,8 +39,7 @@ func runAbapAddonAssemblyKitReserveNextPackages(config *abapAddonAssemblyKitRese | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	err = pollReserveNextPackages(packagesWithRepos, maxRuntimeInMinutes, pollIntervalsInSeconds) | ||||
| 	if err != nil { | ||||
| 	if err = pollReserveNextPackages(packagesWithRepos, utils); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| @@ -104,9 +93,10 @@ func checkAndCopyFieldsToRepositories(pckgWR []aakaas.PackageWithRepository) ([] | ||||
| 	return repos, nil | ||||
| } | ||||
|  | ||||
| func pollReserveNextPackages(pckgWR []aakaas.PackageWithRepository, maxRuntimeInMinutes time.Duration, pollIntervalsInSeconds time.Duration) error { | ||||
| 	timeout := time.After(maxRuntimeInMinutes) | ||||
| 	ticker := time.Tick(pollIntervalsInSeconds) | ||||
| func pollReserveNextPackages(pckgWR []aakaas.PackageWithRepository, utils *aakaas.AakUtils) error { | ||||
| 	pollingInterval := (*utils).GetPollingInterval() | ||||
| 	timeout := time.After((*utils).GetMaxRuntime()) | ||||
| 	ticker := time.Tick(pollingInterval) | ||||
| 	for { | ||||
| 		select { | ||||
| 		case <-timeout: | ||||
| @@ -117,14 +107,14 @@ func pollReserveNextPackages(pckgWR []aakaas.PackageWithRepository, maxRuntimeIn | ||||
| 				err := pckgWR[i].Package.GetPackageAndNamespace() | ||||
| 				// if there is an error, reservation is not yet finished | ||||
| 				if err != nil { | ||||
| 					log.Entry().Infof("Reservation of %s is not yet finished, check again in %s", pckgWR[i].Package.PackageName, pollIntervalsInSeconds) | ||||
| 					log.Entry().Infof("Reservation of %s is not yet finished, check again in %s", pckgWR[i].Package.PackageName, pollingInterval) | ||||
| 					allFinished = false | ||||
| 				} else { | ||||
| 					switch pckgWR[i].Package.Status { | ||||
| 					case aakaas.PackageStatusLocked: | ||||
| 						return fmt.Errorf("Package %s has invalid status 'locked'", pckgWR[i].Package.PackageName) | ||||
| 					case aakaas.PackageStatusCreationTriggered: | ||||
| 						log.Entry().Infof("Reservation of %s is still running with status 'creation triggered', check again in %s", pckgWR[i].Package.PackageName, pollIntervalsInSeconds) | ||||
| 						log.Entry().Infof("Reservation of %s is still running with status 'creation triggered', check again in %s", pckgWR[i].Package.PackageName, pollingInterval) | ||||
| 						allFinished = false | ||||
| 					case aakaas.PackageStatusPlanned: | ||||
| 						log.Entry().Infof("Reservation of %s was successful with status 'planned'", pckgWR[i].Package.PackageName) | ||||
|   | ||||
| @@ -22,6 +22,8 @@ type abapAddonAssemblyKitReserveNextPackagesOptions struct { | ||||
| 	Username                     string `json:"username,omitempty"` | ||||
| 	Password                     string `json:"password,omitempty"` | ||||
| 	AddonDescriptor              string `json:"addonDescriptor,omitempty"` | ||||
| 	MaxRuntimeInMinutes          int    `json:"maxRuntimeInMinutes,omitempty"` | ||||
| 	PollingIntervalInSeconds     int    `json:"pollingIntervalInSeconds,omitempty"` | ||||
| } | ||||
|  | ||||
| type abapAddonAssemblyKitReserveNextPackagesCommonPipelineEnvironment struct { | ||||
| @@ -156,6 +158,8 @@ func addAbapAddonAssemblyKitReserveNextPackagesFlags(cmd *cobra.Command, stepCon | ||||
| 	cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "User for the Addon Assembly Kit as a Service (AAKaaS) system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Password for the Addon Assembly Kit as a Service (AAKaaS) system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.AddonDescriptor, "addonDescriptor", os.Getenv("PIPER_addonDescriptor"), "Structure in the commonPipelineEnvironment containing information about the Product Version and corresponding Software Component Versions") | ||||
| 	cmd.Flags().IntVar(&stepConfig.MaxRuntimeInMinutes, "maxRuntimeInMinutes", 5, "Maximum runtime for status polling in minutes") | ||||
| 	cmd.Flags().IntVar(&stepConfig.PollingIntervalInSeconds, "pollingIntervalInSeconds", 30, "Wait time in seconds between polling calls") | ||||
|  | ||||
| 	cmd.MarkFlagRequired("abapAddonAssemblyKitEndpoint") | ||||
| 	cmd.MarkFlagRequired("username") | ||||
| @@ -218,6 +222,24 @@ func abapAddonAssemblyKitReserveNextPackagesMetadata() config.StepData { | ||||
| 						Aliases:   []config.Alias{}, | ||||
| 						Default:   os.Getenv("PIPER_addonDescriptor"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "maxRuntimeInMinutes", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "int", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     5, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "pollingIntervalInSeconds", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "int", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     30, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			Outputs: config.StepOutputs{ | ||||
|   | ||||
| @@ -17,8 +17,8 @@ func TestReserveNextPackagesStep(t *testing.T) { | ||||
| 	config.Username = "dummy" | ||||
| 	config.Password = "dummy" | ||||
| 	var cpe abapAddonAssemblyKitReserveNextPackagesCommonPipelineEnvironment | ||||
| 	timeout := time.Duration(5 * time.Second) | ||||
| 	pollInterval := time.Duration(1 * time.Second) | ||||
| 	bundle := aakaas.NewAakBundleMock() | ||||
| 	utils := bundle.GetUtils() | ||||
| 	t.Run("step success", func(t *testing.T) { | ||||
| 		addonDescriptor := abaputils.AddonDescriptor{ | ||||
| 			Repositories: []abaputils.Repository{ | ||||
| @@ -36,12 +36,9 @@ func TestReserveNextPackagesStep(t *testing.T) { | ||||
| 		} | ||||
| 		adoDesc, _ := json.Marshal(addonDescriptor) | ||||
| 		config.AddonDescriptor = string(adoDesc) | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			BodyList: []string{responseReserveNextPackageReleased, responseReserveNextPackagePlanned, responseReserveNextPackagePostReleased, "myToken", responseReserveNextPackagePostPlanned, "myToken"}, | ||||
| 		} | ||||
| 		err := runAbapAddonAssemblyKitReserveNextPackages(&config, nil, client, &cpe, timeout, pollInterval) | ||||
|  | ||||
| 		bodyList := []string{responseReserveNextPackageReleased, responseReserveNextPackagePlanned, responseReserveNextPackagePostReleased, "myToken", responseReserveNextPackagePostPlanned, "myToken"} | ||||
| 		bundle.SetBodyList(bodyList) | ||||
| 		err := runAbapAddonAssemblyKitReserveNextPackages(&config, nil, &utils, &cpe) | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		var addonDescriptorFinal abaputils.AddonDescriptor | ||||
| 		json.Unmarshal([]byte(cpe.abap.addonDescriptor), &addonDescriptorFinal) | ||||
| @@ -58,9 +55,7 @@ func TestReserveNextPackagesStep(t *testing.T) { | ||||
| 		} | ||||
| 		adoDesc, _ := json.Marshal(addonDescriptor) | ||||
| 		config.AddonDescriptor = string(adoDesc) | ||||
|  | ||||
| 		client := &abaputils.ClientMock{} | ||||
| 		err := runAbapAddonAssemblyKitReserveNextPackages(&config, nil, client, &cpe, timeout, pollInterval) | ||||
| 		err := runAbapAddonAssemblyKitReserveNextPackages(&config, nil, &utils, &cpe) | ||||
| 		assert.Error(t, err, "Did expect error") | ||||
| 	}) | ||||
| 	t.Run("step error - timeout", func(t *testing.T) { | ||||
| @@ -74,12 +69,10 @@ func TestReserveNextPackagesStep(t *testing.T) { | ||||
| 		} | ||||
| 		adoDesc, _ := json.Marshal(addonDescriptor) | ||||
| 		config.AddonDescriptor = string(adoDesc) | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			BodyList: []string{responseReserveNextPackageCreationTriggered, responseReserveNextPackagePostPlanned, "myToken"}, | ||||
| 		} | ||||
| 		timeout := time.Duration(1 * time.Second) | ||||
| 		err := runAbapAddonAssemblyKitReserveNextPackages(&config, nil, client, &cpe, timeout, pollInterval) | ||||
| 		bodyList := []string{responseReserveNextPackageCreationTriggered, responseReserveNextPackagePostPlanned, "myToken"} | ||||
| 		bundle.SetBodyList(bodyList) | ||||
| 		bundle.SetMaxRuntime(time.Duration(1 * time.Microsecond)) | ||||
| 		err := runAbapAddonAssemblyKitReserveNextPackages(&config, nil, &utils, &cpe) | ||||
| 		assert.Error(t, err, "Did expect error") | ||||
| 	}) | ||||
| } | ||||
| @@ -251,62 +244,53 @@ func TestReservePackages(t *testing.T) { | ||||
| // ********************* Test pollReserveNextPackages ******************* | ||||
|  | ||||
| func TestPollReserveNextPackages(t *testing.T) { | ||||
| 	timeout := time.Duration(5 * time.Second) | ||||
| 	pollInterval := time.Duration(1 * time.Second) | ||||
| 	bundle := aakaas.NewAakBundleMock() | ||||
| 	utils := bundle.GetUtils() | ||||
| 	t.Run("test pollReserveNextPackages - testing loop", func(t *testing.T) { | ||||
| 		client := abaputils.ClientMock{ | ||||
| 			BodyList: []string{responseReserveNextPackagePlanned, responseReserveNextPackageCreationTriggered}, | ||||
| 		} | ||||
| 		pckgWR := testPollPackagesSetup(client) | ||||
| 		err := pollReserveNextPackages(pckgWR, timeout, pollInterval) | ||||
| 		bodyList := []string{responseReserveNextPackagePlanned, responseReserveNextPackageCreationTriggered} | ||||
| 		bundle.SetBodyList(bodyList) | ||||
| 		pckgWR := testPollPackagesSetup(&utils) | ||||
| 		err := pollReserveNextPackages(pckgWR, &utils) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, aakaas.PackageStatusPlanned, pckgWR[0].Package.Status) | ||||
| 		assert.Equal(t, "/DRNMSPC/", pckgWR[0].Package.Namespace) | ||||
| 	}) | ||||
| 	t.Run("test pollReserveNextPackages - status locked", func(t *testing.T) { | ||||
| 		client := abaputils.ClientMock{ | ||||
| 			Body: responseReserveNextPackageLocked, | ||||
| 		} | ||||
| 		pckgWR := testPollPackagesSetup(client) | ||||
| 		err := pollReserveNextPackages(pckgWR, timeout, pollInterval) | ||||
| 		bundle.SetBody(responseReserveNextPackageLocked) | ||||
| 		pckgWR := testPollPackagesSetup(&utils) | ||||
| 		err := pollReserveNextPackages(pckgWR, &utils) | ||||
| 		assert.Error(t, err) | ||||
| 		assert.Equal(t, aakaas.PackageStatusLocked, pckgWR[0].Package.Status) | ||||
| 	}) | ||||
| 	t.Run("test pollReserveNextPackages - status released", func(t *testing.T) { | ||||
| 		client := abaputils.ClientMock{ | ||||
| 			Body: responseReserveNextPackageReleased, | ||||
| 		} | ||||
| 		pckgWR := testPollPackagesSetup(client) | ||||
| 		err := pollReserveNextPackages(pckgWR, timeout, pollInterval) | ||||
| 		bundle.SetBody(responseReserveNextPackageReleased) | ||||
| 		pckgWR := testPollPackagesSetup(&utils) | ||||
| 		err := pollReserveNextPackages(pckgWR, &utils) | ||||
| 		assert.NoError(t, err) | ||||
| 		assert.Equal(t, aakaas.PackageStatusReleased, pckgWR[0].Package.Status) | ||||
| 	}) | ||||
| 	t.Run("test pollReserveNextPackages - unknow status", func(t *testing.T) { | ||||
| 		client := abaputils.ClientMock{ | ||||
| 			Body: responseReserveNextPackageUnknownState, | ||||
| 		} | ||||
| 		pckgWR := testPollPackagesSetup(client) | ||||
| 		err := pollReserveNextPackages(pckgWR, timeout, pollInterval) | ||||
| 		bundle.SetBody(responseReserveNextPackageUnknownState) | ||||
| 		pckgWR := testPollPackagesSetup(&utils) | ||||
| 		err := pollReserveNextPackages(pckgWR, &utils) | ||||
| 		assert.Error(t, err) | ||||
| 		assert.Equal(t, aakaas.PackageStatus("X"), pckgWR[0].Package.Status) | ||||
| 	}) | ||||
| 	t.Run("test pollReserveNextPackages - timeout", func(t *testing.T) { | ||||
| 		client := abaputils.ClientMock{ | ||||
| 			Body:  "ErrorBody", | ||||
| 			Error: errors.New("Failure during reserve next"), | ||||
| 		} | ||||
| 		pckgWR := testPollPackagesSetup(client) | ||||
| 		timeout := time.Duration(2 * time.Second) | ||||
| 		err := pollReserveNextPackages(pckgWR, timeout, pollInterval) | ||||
| 		bundle.SetBody(responseReserveNextPackageUnknownState) | ||||
| 		bundle.SetError("Failure during reserve next") | ||||
| 		bundle.SetMaxRuntime(time.Duration(1 * time.Microsecond)) | ||||
| 		pckgWR := testPollPackagesSetup(&utils) | ||||
| 		err := pollReserveNextPackages(pckgWR, &utils) | ||||
| 		assert.Error(t, err) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // ********************* Setup functions ******************* | ||||
|  | ||||
| func testPollPackagesSetup(client abaputils.ClientMock) []aakaas.PackageWithRepository { | ||||
| func testPollPackagesSetup(utils *aakaas.AakUtils) []aakaas.PackageWithRepository { | ||||
| 	conn := new(abapbuild.Connector) | ||||
| 	conn.Client = &client | ||||
| 	conn.Client = *utils | ||||
| 	conn.Header = make(map[string][]string) | ||||
| 	pckgWR := []aakaas.PackageWithRepository{ | ||||
| 		{ | ||||
|   | ||||
							
								
								
									
										61
									
								
								pkg/abap/aakaas/aakUtils.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								pkg/abap/aakaas/aakUtils.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,61 @@ | ||||
| package aakaas | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
|  | ||||
| 	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" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| ) | ||||
|  | ||||
| type AakUtils interface { | ||||
| 	command.ExecRunner | ||||
| 	abapbuild.HTTPSendLoader | ||||
| 	ReadAddonDescriptor(FileName string) (abaputils.AddonDescriptor, error) | ||||
| 	GetMaxRuntime() time.Duration | ||||
| 	GetPollingInterval() time.Duration | ||||
| } | ||||
|  | ||||
| type AakBundle struct { | ||||
| 	*command.Command | ||||
| 	*piperhttp.Client | ||||
| 	maxRuntime      time.Duration | ||||
| 	pollingInterval time.Duration | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundle) GetMaxRuntime() time.Duration { | ||||
| 	return bundle.maxRuntime | ||||
| } | ||||
| func (bundle *AakBundle) GetPollingInterval() time.Duration { | ||||
| 	return bundle.pollingInterval | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundle) ReadAddonDescriptor(FileName string) (abaputils.AddonDescriptor, error) { | ||||
| 	return abaputils.ReadAddonDescriptor(FileName) | ||||
| } | ||||
|  | ||||
| func NewAakBundleWithTime(maxRuntime time.Duration, pollingInterval time.Duration) AakUtils { | ||||
| 	utils := AakBundle{ | ||||
| 		Command:         &command.Command{}, | ||||
| 		Client:          &piperhttp.Client{}, | ||||
| 		maxRuntime:      maxRuntime * time.Minute, | ||||
| 		pollingInterval: pollingInterval * time.Second, | ||||
| 	} | ||||
| 	// Reroute command output to logging framework | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func NewAakBundle() AakUtils { | ||||
| 	utils := AakBundle{ | ||||
| 		Command: &command.Command{}, | ||||
| 		Client:  &piperhttp.Client{}, | ||||
| 	} | ||||
| 	// Reroute command output to logging framework | ||||
| 	utils.Stdout(log.Writer()) | ||||
| 	utils.Stderr(log.Writer()) | ||||
| 	return &utils | ||||
| } | ||||
							
								
								
									
										131
									
								
								pkg/abap/aakaas/aakUtils_mock.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								pkg/abap/aakaas/aakUtils_mock.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | ||||
| //go:build !release | ||||
| // +build !release | ||||
|  | ||||
| package aakaas | ||||
|  | ||||
| import ( | ||||
| 	"time" | ||||
|  | ||||
| 	abapbuild "github.com/SAP/jenkins-library/pkg/abap/build" | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/mock" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| type AakBundleMock struct { | ||||
| 	*mock.ExecMockRunner | ||||
| 	*abaputils.ClientMock | ||||
| 	maxRuntime time.Duration | ||||
| } | ||||
|  | ||||
| func NewAakBundleMock() *AakBundleMock { | ||||
| 	utils := AakBundleMock{ | ||||
| 		ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 		ClientMock:     &abaputils.ClientMock{}, | ||||
| 		maxRuntime:     1 * time.Second, | ||||
| 	} | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMock) GetUtils() AakUtils { | ||||
| 	return bundle | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMock) GetMaxRuntime() time.Duration { | ||||
| 	return bundle.maxRuntime | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMock) SetMaxRuntime(maxRuntime time.Duration) { | ||||
| 	bundle.maxRuntime = maxRuntime | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMock) GetPollingInterval() time.Duration { | ||||
| 	return 1 * time.Microsecond | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMock) SetBodyList(bodyList []string) { | ||||
| 	bundle.ClientMock.Body = "" | ||||
| 	bundle.ClientMock.BodyList = bodyList | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMock) SetBody(body string) { | ||||
| 	bundle.ClientMock.Body = body | ||||
| 	bundle.ClientMock.BodyList = []string{} | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMock) SetError(errorText string) { | ||||
| 	bundle.ClientMock.Error = errors.New(errorText) | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMock) ReadAddonDescriptor(FileName string) (abaputils.AddonDescriptor, error) { | ||||
| 	var addonDescriptor abaputils.AddonDescriptor | ||||
| 	var err error | ||||
| 	switch FileName { | ||||
| 	case "success": | ||||
| 		{ | ||||
| 			addonDescriptor = abaputils.AddonDescriptor{ | ||||
| 				AddonProduct:     "/DRNMSPC/PRD01", | ||||
| 				AddonVersionYAML: "3.2.1", | ||||
| 				Repositories: []abaputils.Repository{ | ||||
| 					{ | ||||
| 						Name:        "/DRNMSPC/COMP01", | ||||
| 						VersionYAML: "1.2.3", | ||||
| 						CommitID:    "HUGO1234", | ||||
| 					}, | ||||
| 				}, | ||||
| 			} | ||||
| 		} | ||||
| 	case "noCommitID": | ||||
| 		{ | ||||
| 			addonDescriptor = abaputils.AddonDescriptor{ | ||||
| 				AddonProduct:     "/DRNMSPC/PRD01", | ||||
| 				AddonVersionYAML: "3.2.1", | ||||
| 				Repositories: []abaputils.Repository{ | ||||
| 					{ | ||||
| 						Name:        "/DRNMSPC/COMP01", | ||||
| 						VersionYAML: "1.2.3", | ||||
| 					}, | ||||
| 				}, | ||||
| 			} | ||||
| 		} | ||||
| 	case "failing": | ||||
| 		{ | ||||
| 			err = errors.New("error in ReadAddonDescriptor") | ||||
| 		} | ||||
| 	} | ||||
| 	return addonDescriptor, err | ||||
| } | ||||
|  | ||||
| //*****************************other client mock ******************************* | ||||
| type AakBundleMockNewMC struct { | ||||
| 	*mock.ExecMockRunner | ||||
| 	*abapbuild.MockClient | ||||
| 	maxRuntime time.Duration | ||||
| } | ||||
|  | ||||
| func NewAakBundleMockNewMC(mC *abapbuild.MockClient) *AakBundleMockNewMC { | ||||
| 	utils := AakBundleMockNewMC{ | ||||
| 		ExecMockRunner: &mock.ExecMockRunner{}, | ||||
| 		MockClient:     mC, | ||||
| 		maxRuntime:     1 * time.Second, | ||||
| 	} | ||||
| 	return &utils | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMockNewMC) GetUtils() AakUtils { | ||||
| 	return bundle | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMockNewMC) GetMaxRuntime() time.Duration { | ||||
| 	return bundle.maxRuntime | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMockNewMC) GetPollingInterval() time.Duration { | ||||
| 	return 1 * time.Microsecond | ||||
| } | ||||
|  | ||||
| func (bundle *AakBundleMockNewMC) ReadAddonDescriptor(FileName string) (abaputils.AddonDescriptor, error) { | ||||
| 	var addonDescriptor abaputils.AddonDescriptor | ||||
| 	err := errors.New("don't use this") | ||||
| 	return addonDescriptor, err | ||||
| } | ||||
| @@ -2,12 +2,12 @@ package aakaas | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/url" | ||||
|  | ||||
| 	abapbuild "github.com/SAP/jenkins-library/pkg/abap/build" | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| // PackageStatus : Status of an ABAP delivery package | ||||
| @@ -79,13 +79,15 @@ func (p *Package) ReserveNext() error { | ||||
| 	} | ||||
| 	log.Entry().Infof("Reserve package for %s version %s", p.ComponentName, p.VersionYAML) | ||||
| 	p.Connector.GetToken("/odata/aas_ocs_package") | ||||
| 	appendum := "/odata/aas_ocs_package/DeterminePackageForScv?Name='" + p.ComponentName + "'&Version='" + p.VersionYAML + "'" | ||||
| 	appendum := "/odata/aas_ocs_package/DeterminePackageForScv?Name='" + url.QueryEscape(p.ComponentName) + "'&Version='" + url.QueryEscape(p.VersionYAML) + "'" | ||||
| 	body, err := p.Connector.Post(appendum, "") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	var jPck jsonPackageDeterminePackageForScv | ||||
| 	json.Unmarshal(body, &jPck) | ||||
| 	if err := json.Unmarshal(body, &jPck); err != nil { | ||||
| 		return errors.Wrap(err, "Unexpected AAKaaS response for reserve package: "+string(body)) | ||||
| 	} | ||||
| 	p.PackageName = jPck.DeterminePackage.Package.PackageName | ||||
| 	p.Type = jPck.DeterminePackage.Package.Type | ||||
| 	p.PredecessorCommitID = jPck.DeterminePackage.Package.PredecessorCommitID | ||||
| @@ -98,13 +100,15 @@ func (p *Package) ReserveNext() error { | ||||
|  | ||||
| // GetPackageAndNamespace : retrieve attributes of the package from AAKaaS | ||||
| func (p *Package) GetPackageAndNamespace() error { | ||||
| 	appendum := "/odata/aas_ocs_package/OcsPackageSet('" + p.PackageName + "')" | ||||
| 	appendum := "/odata/aas_ocs_package/OcsPackageSet('" + url.QueryEscape(p.PackageName) + "')" | ||||
| 	body, err := p.Connector.Get(appendum) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	var jPck jsonPackage | ||||
| 	json.Unmarshal(body, &jPck) | ||||
| 	if err := json.Unmarshal(body, &jPck); err != nil { | ||||
| 		return errors.Wrap(err, "Unexpected AAKaaS response for check of package status: "+string(body)) | ||||
| 	} | ||||
| 	p.Status = jPck.Package.Status | ||||
| 	p.Namespace = jPck.Package.Namespace | ||||
| 	return nil | ||||
| @@ -122,16 +126,15 @@ func (p *Package) Register() error { | ||||
| 	} | ||||
| 	log.Entry().Infof("Register package %s", p.PackageName) | ||||
| 	p.Connector.GetToken("/odata/aas_ocs_package") | ||||
| 	appendum := "/odata/aas_ocs_package/RegisterPackage?Name='" + p.PackageName + "'" | ||||
| 	appendum := "/odata/aas_ocs_package/RegisterPackage?Name='" + url.QueryEscape(p.PackageName) + "'" | ||||
| 	body, err := p.Connector.Post(appendum, "") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var jPck jsonPackage | ||||
| 	err = json.Unmarshal(body, &jPck) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to parse package status from response: %w", err) | ||||
| 	if err := json.Unmarshal(body, &jPck); err != nil { | ||||
| 		return errors.Wrap(err, "Unexpected AAKaaS response for register package: "+string(body)) | ||||
| 	} | ||||
| 	p.Status = jPck.Package.Status | ||||
| 	log.Entry().Infof("Package status %s", p.Status) | ||||
| @@ -144,13 +147,15 @@ func (p *Package) Release() error { | ||||
| 	var err error | ||||
| 	log.Entry().Infof("Release package %s", p.PackageName) | ||||
| 	p.Connector.GetToken("/odata/aas_ocs_package") | ||||
| 	appendum := "/odata/aas_ocs_package/ReleasePackage?Name='" + p.PackageName + "'" | ||||
| 	appendum := "/odata/aas_ocs_package/ReleasePackage?Name='" + url.QueryEscape(p.PackageName) + "'" | ||||
| 	body, err = p.Connector.Post(appendum, "") | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	var jPck jsonPackage | ||||
| 	json.Unmarshal(body, &jPck) | ||||
| 	if err := json.Unmarshal(body, &jPck); err != nil { | ||||
| 		return errors.Wrap(err, "Unexpected AAKaaS response for release package: "+string(body)) | ||||
| 	} | ||||
| 	p.Status = jPck.Package.Status | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package build | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"net/url" | ||||
| 	"path" | ||||
| 	"path/filepath" | ||||
| 	"sort" | ||||
| @@ -43,17 +44,35 @@ const ( | ||||
| ) | ||||
|  | ||||
| //******** structs needed for json convertion ******** | ||||
|  | ||||
| type jsonBuild struct { | ||||
| 	Build *Build `json:"d"` | ||||
| 	Build struct { | ||||
| 		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"` | ||||
| 	} `json:"d"` | ||||
| } | ||||
|  | ||||
| type jsonTasks struct { | ||||
| 	ResultTasks struct { | ||||
| 		Tasks []task `json:"results"` | ||||
| 		Tasks []jsonTask `json:"results"` | ||||
| 	} `json:"d"` | ||||
| } | ||||
|  | ||||
| type jsonTask struct { | ||||
| 	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"` | ||||
| } | ||||
|  | ||||
| type jsonLogs struct { | ||||
| 	ResultLogs struct { | ||||
| 		Logs []logStruct `json:"results"` | ||||
| @@ -162,7 +181,9 @@ func (b *Build) Start(phase string, inputValues Values) error { | ||||
| 	} | ||||
|  | ||||
| 	var jBuild jsonBuild | ||||
| 	json.Unmarshal(body, &jBuild) | ||||
| 	if err := json.Unmarshal(body, &jBuild); err != nil { | ||||
| 		return errors.Wrap(err, "Unexpected buildFrameWork response: "+string(body)) | ||||
| 	} | ||||
| 	b.BuildID = jBuild.Build.BuildID | ||||
| 	b.RunState = jBuild.Build.RunState | ||||
| 	b.ResultState = jBuild.Build.ResultState | ||||
| @@ -209,13 +230,15 @@ func (b *Build) EvaluteIfBuildSuccessful(treatWarningsAsError bool) error { | ||||
|  | ||||
| // Get : Get all Build tasks | ||||
| func (b *Build) Get() error { | ||||
| 	appendum := "/builds('" + b.BuildID + "')" | ||||
| 	appendum := "/builds('" + url.QueryEscape(b.BuildID) + "')" | ||||
| 	body, err := b.Connector.Get(appendum) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	var jBuild jsonBuild | ||||
| 	json.Unmarshal(body, &jBuild) | ||||
| 	if err := json.Unmarshal(body, &jBuild); err != nil { | ||||
| 		return errors.Wrap(err, "Unexpected buildFrameWork response: "+string(body)) | ||||
| 	} | ||||
| 	b.RunState = jBuild.Build.RunState | ||||
| 	b.ResultState = jBuild.Build.ResultState | ||||
| 	b.Phase = jBuild.Build.Phase | ||||
| @@ -228,20 +251,18 @@ func (b *Build) Get() error { | ||||
|  | ||||
| func (b *Build) getTasks() error { | ||||
| 	if len(b.Tasks) == 0 { | ||||
| 		appendum := "/builds('" + b.BuildID + "')/tasks" | ||||
| 		appendum := "/builds('" + url.QueryEscape(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 | ||||
| 		b.Tasks, err = unmarshalTasks(body, b.Connector) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		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 | ||||
| } | ||||
| @@ -249,13 +270,15 @@ func (b *Build) getTasks() error { | ||||
| // GetValues : Gets all Build values | ||||
| func (b *Build) GetValues() error { | ||||
| 	if len(b.Values) == 0 { | ||||
| 		appendum := "/builds('" + b.BuildID + "')/values" | ||||
| 		appendum := "/builds('" + url.QueryEscape(b.BuildID) + "')/values" | ||||
| 		body, err := b.Connector.Get(appendum) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		var jValues jsonValues | ||||
| 		json.Unmarshal(body, &jValues) | ||||
| 		if err := json.Unmarshal(body, &jValues); err != nil { | ||||
| 			return errors.Wrap(err, "Unexpected buildFrameWork response: "+string(body)) | ||||
| 		} | ||||
| 		b.Values = jValues.ResultValues.Values | ||||
| 		for i := range b.Values { | ||||
| 			b.Values[i].connector = b.Connector | ||||
| @@ -346,13 +369,15 @@ func (b *Build) IsFinished() bool { | ||||
|  | ||||
| func (t *task) getLogs() error { | ||||
| 	if len(t.Logs) == 0 { | ||||
| 		appendum := fmt.Sprint("/tasks(build_id='", t.BuildID, "',task_id=", t.TaskID, ")/logs") | ||||
| 		appendum := fmt.Sprint("/tasks(build_id='", url.QueryEscape(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) | ||||
| 		if err := json.Unmarshal(body, &jLogs); err != nil { | ||||
| 			return errors.Wrap(err, "Unexpected buildFrameWork response: "+string(body)) | ||||
| 		} | ||||
| 		t.Logs = jLogs.ResultLogs.Logs | ||||
| 	} | ||||
| 	return nil | ||||
| @@ -360,13 +385,15 @@ func (t *task) getLogs() error { | ||||
|  | ||||
| func (t *task) getResults() error { | ||||
| 	if len(t.Results) == 0 { | ||||
| 		appendum := fmt.Sprint("/tasks(build_id='", t.BuildID, "',task_id=", t.TaskID, ")/results") | ||||
| 		appendum := fmt.Sprint("/tasks(build_id='", url.QueryEscape(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) | ||||
| 		if err := json.Unmarshal(body, &jResults); err != nil { | ||||
| 			return errors.Wrap(err, "Unexpected buildFrameWork response: "+string(body)) | ||||
| 		} | ||||
| 		t.Results = jResults.ResultResults.Results | ||||
| 		for i := range t.Results { | ||||
| 			t.Results[i].connector = t.connector | ||||
| @@ -452,7 +479,7 @@ func (b *Build) PublishDownloadedResults(stepname string, filenames []string, pu | ||||
|  | ||||
| // 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") | ||||
| 	appendum := fmt.Sprint("/results(build_id='", url.QueryEscape(result.BuildID), "',task_id=", result.TaskID, ",name='", url.QueryEscape(result.Name), "')/$value") | ||||
| 	err := result.connector.Download(appendum, downloadPath) | ||||
| 	return err | ||||
| } | ||||
| @@ -543,6 +570,29 @@ func (in inputForPost) String() string { | ||||
| 	return fmt.Sprintf(`{ "phase": "%s", "values": [%s]}`, in.phase, in.values.String()) | ||||
| } | ||||
|  | ||||
| //******** unmarshal function  ************ | ||||
| func unmarshalTasks(body []byte, connector Connector) ([]task, error) { | ||||
|  | ||||
| 	var tasks []task | ||||
| 	var append_task task | ||||
| 	var jTasks jsonTasks | ||||
| 	if err := json.Unmarshal(body, &jTasks); err != nil { | ||||
| 		return tasks, errors.Wrap(err, "Unexpected buildFrameWork response: "+string(body)) | ||||
| 	} | ||||
| 	for _, jTask := range jTasks.ResultTasks.Tasks { | ||||
| 		append_task.connector = connector | ||||
| 		append_task.BuildID = jTask.BuildID | ||||
| 		append_task.TaskID = jTask.TaskID | ||||
| 		append_task.LogID = jTask.LogID | ||||
| 		append_task.PluginClass = jTask.PluginClass | ||||
| 		append_task.StartedAt = jTask.StartedAt | ||||
| 		append_task.FinishedAt = jTask.FinishedAt | ||||
| 		append_task.ResultState = jTask.ResultState | ||||
| 		tasks = append(tasks, append_task) | ||||
| 	} | ||||
| 	return tasks, nil | ||||
| } | ||||
|  | ||||
| // *****************publish ******************************* | ||||
| type Publish interface { | ||||
| 	PersistReportsAndLinks(stepName, workspace string, reports, links []piperutils.Path) | ||||
|   | ||||
| @@ -162,7 +162,7 @@ func TestPoll(t *testing.T) { | ||||
| 	t.Run("Poll timeout", func(t *testing.T) { | ||||
| 		//arrange | ||||
| 		build.BuildID = "AKO22FYOFYPOXHOBVKXUTX3A3Q" | ||||
| 		conn.MaxRuntime = time.Duration(2 * time.Microsecond) | ||||
| 		conn.MaxRuntime = time.Duration(1 * time.Microsecond) | ||||
| 		conn.PollingInterval = time.Duration(1 * time.Microsecond) | ||||
| 		mc := NewMockClient() | ||||
| 		mc.AddData(buildGet1) | ||||
|   | ||||
| @@ -48,6 +48,24 @@ spec: | ||||
|         resourceRef: | ||||
|           - name: commonPipelineEnvironment | ||||
|             param: abap/addonDescriptor | ||||
|       - name: maxRuntimeInMinutes | ||||
|         type: int | ||||
|         description: Maximum runtime for status polling in minutes | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         default: 5 | ||||
|       - name: pollingIntervalInSeconds | ||||
|         type: int | ||||
|         description: Wait time in seconds between polling calls | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         default: 30 | ||||
|   outputs: | ||||
|     resources: | ||||
|       - name: commonPipelineEnvironment | ||||
|   | ||||
| @@ -54,6 +54,24 @@ spec: | ||||
|         resourceRef: | ||||
|           - name: commonPipelineEnvironment | ||||
|             param: abap/addonDescriptor | ||||
|       - name: maxRuntimeInMinutes | ||||
|         type: int | ||||
|         description: Maximum runtime for status polling in minutes | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         default: 5 | ||||
|       - name: pollingIntervalInSeconds | ||||
|         type: int | ||||
|         description: Wait time in seconds between polling calls | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         default: 30 | ||||
|   outputs: | ||||
|     resources: | ||||
|       - name: commonPipelineEnvironment | ||||
|   | ||||
		Reference in New Issue
	
	Block a user