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 
			
		
		
		
	Adding log download as zip archive (#5121)
* adding LogOutput to clone step * delete comments * adding stepName * change step name * adding multiple log archive outputs files * changing file name * change filename * change time format * adding second file for testing * adding second file * change structure for PersistReportsAndLinks * change to pointer * change pointer * cleanup * changing file name * adding logArchive for pull action * adding logArchive for checkoutBranch * refactor zip archive log * change structure * adding PersistArchiveLogsForPiperStep function * adding persist structure to checkout * adding FileNameStep * adding unit tests * correct name * change whitespace in yaml * fixing unit tests * fixing createTag unit test * fixing unit test * fixing unit test * rename ArchiveOutputLogs to LogOutputManager * refactor pointer structure * adopt tests to pointer structure * fixing / error in repo name * adding log overview also after archive log * change log output structure * adding always execution log * update unit tests --------- Co-authored-by: Daniel Mieg <56156797+DanielMieg@users.noreply.github.com>
This commit is contained in:
		| @@ -9,6 +9,7 @@ import ( | ||||
| 	"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" | ||||
| ) | ||||
| @@ -30,14 +31,23 @@ func abapEnvironmentCheckoutBranch(options abapEnvironmentCheckoutBranchOptions, | ||||
| 		PollIntervall: 5 * time.Second, | ||||
| 	} | ||||
|  | ||||
| 	var reports []piperutils.Path | ||||
|  | ||||
| 	logOutputManager := abaputils.LogOutputManager{ | ||||
| 		LogOutput:    options.LogOutput, | ||||
| 		PiperStep:    "checkoutBranch", | ||||
| 		FileNameStep: "checkoutBranch", | ||||
| 		StepReports:  reports, | ||||
| 	} | ||||
|  | ||||
| 	// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end | ||||
| 	err := runAbapEnvironmentCheckoutBranch(&options, &autils, &apiManager) | ||||
| 	err := runAbapEnvironmentCheckoutBranch(&options, &autils, &apiManager, &logOutputManager) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runAbapEnvironmentCheckoutBranch(options *abapEnvironmentCheckoutBranchOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { | ||||
| func runAbapEnvironmentCheckoutBranch(options *abapEnvironmentCheckoutBranchOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { | ||||
|  | ||||
| 	// Mapping for options | ||||
| 	subOptions := convertCheckoutConfig(options) | ||||
| @@ -58,19 +68,24 @@ func runAbapEnvironmentCheckoutBranch(options *abapEnvironmentCheckoutBranchOpti | ||||
| 	if err != nil { | ||||
| 		return errors.Wrap(err, "Could not read repositories") | ||||
| 	} | ||||
| 	err = checkoutBranches(repositories, connectionDetails, apiManager) | ||||
|  | ||||
| 	err = checkoutBranches(repositories, connectionDetails, apiManager, logOutputManager) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("Something failed during the checkout: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	// Persist log archive | ||||
| 	abaputils.PersistArchiveLogsForPiperStep(logOutputManager) | ||||
|  | ||||
| 	log.Entry().Infof("-------------------------") | ||||
| 	log.Entry().Info("All branches were checked out successfully") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func checkoutBranches(repositories []abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { | ||||
| func checkoutBranches(repositories []abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { | ||||
| 	log.Entry().Infof("Start switching %v branches", len(repositories)) | ||||
| 	for _, repo := range repositories { | ||||
| 		err = handleCheckout(repo, checkoutConnectionDetails, apiManager) | ||||
| 		err = handleCheckout(repo, checkoutConnectionDetails, apiManager, logOutputManager) | ||||
| 		if err != nil { | ||||
| 			break | ||||
| 		} | ||||
| @@ -96,7 +111,7 @@ func checkCheckoutBranchRepositoryConfiguration(options abapEnvironmentCheckoutB | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func handleCheckout(repo abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { | ||||
| func handleCheckout(repo abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { | ||||
|  | ||||
| 	if reflect.DeepEqual(abaputils.Repository{}, repo) { | ||||
| 		return fmt.Errorf("Failed to read repository configuration: %w", errors.New("Error in configuration, most likely you have entered empty or wrong configuration values. Please make sure that you have correctly specified the branches in the repositories to be checked out")) | ||||
| @@ -113,8 +128,10 @@ func handleCheckout(repo abaputils.Repository, checkoutConnectionDetails abaputi | ||||
| 		return fmt.Errorf("Failed to trigger Checkout: %w", errors.New("Checkout of "+repo.Branch+" for software component "+repo.Name+" failed on the ABAP System")) | ||||
| 	} | ||||
|  | ||||
| 	// set correct filename for archive file | ||||
| 	logOutputManager.FileNameStep = "checkoutBranch" | ||||
| 	// Polling the status of the repository import on the ABAP Environment system | ||||
| 	status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall()) | ||||
| 	status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall(), logOutputManager) | ||||
| 	if errorPollEntity != nil { | ||||
| 		return fmt.Errorf("Failed to poll Checkout: %w", errors.New("Status of checkout action on repository"+repo.Name+" failed on the ABAP System")) | ||||
| 	} | ||||
|   | ||||
| @@ -22,6 +22,7 @@ type abapEnvironmentCheckoutBranchOptions struct { | ||||
| 	BranchName        string   `json:"branchName,omitempty"` | ||||
| 	Host              string   `json:"host,omitempty"` | ||||
| 	Repositories      string   `json:"repositories,omitempty"` | ||||
| 	LogOutput         string   `json:"logOutput,omitempty" validate:"possible-values=ZIP STANDARD"` | ||||
| 	CfAPIEndpoint     string   `json:"cfApiEndpoint,omitempty"` | ||||
| 	CfOrg             string   `json:"cfOrg,omitempty"` | ||||
| 	CfSpace           string   `json:"cfSpace,omitempty"` | ||||
| @@ -142,6 +143,7 @@ func addAbapEnvironmentCheckoutBranchFlags(cmd *cobra.Command, stepConfig *abapE | ||||
| 	cmd.Flags().StringVar(&stepConfig.BranchName, "branchName", os.Getenv("PIPER_branchName"), "Specifies a Branch of a Repository (Software Component) on the SAP BTP ABAP Environment system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Host, "host", os.Getenv("PIPER_host"), "Specifies the host address of the SAP BTP ABAP Environment system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Repositories, "repositories", os.Getenv("PIPER_repositories"), "Specifies a YAML file containing the repositories configuration") | ||||
| 	cmd.Flags().StringVar(&stepConfig.LogOutput, "logOutput", `STANDARD`, "Specifies how the clone logs from the Manage Software Components App are displayed or saved") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfAPIEndpoint, "cfApiEndpoint", os.Getenv("PIPER_cfApiEndpoint"), "Cloud Foundry API Enpoint") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "Cloud Foundry target organization") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfSpace, "cfSpace", os.Getenv("PIPER_cfSpace"), "Cloud Foundry target space") | ||||
| @@ -233,6 +235,15 @@ func abapEnvironmentCheckoutBranchMetadata() config.StepData { | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_repositories"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "logOutput", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     `STANDARD`, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "cfApiEndpoint", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| @@ -51,6 +52,7 @@ func TestCheckoutBranchStep(t *testing.T) { | ||||
| 			Password:          "testPassword", | ||||
| 			RepositoryName:    "testRepo1", | ||||
| 			BranchName:        "testBranch", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` | ||||
| @@ -67,8 +69,16 @@ func TestCheckoutBranchStep(t *testing.T) { | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "checkoutBranch", | ||||
| 			FileNameStep: "checkoutBranch", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 	}) | ||||
| 	t.Run("Run Step Failure - empty config", func(t *testing.T) { | ||||
| @@ -96,8 +106,16 @@ func TestCheckoutBranchStep(t *testing.T) { | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    "STANDARD", | ||||
| 			PiperStep:    "checkoutBranch", | ||||
| 			FileNameStep: "checkoutBranch", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.EqualError(t, err, expectedErrorMessage) | ||||
| 	}) | ||||
| 	t.Run("Run Step Failure - wrong status", func(t *testing.T) { | ||||
| @@ -120,6 +138,7 @@ func TestCheckoutBranchStep(t *testing.T) { | ||||
| 			Password:          "testPassword", | ||||
| 			RepositoryName:    "testRepo1", | ||||
| 			BranchName:        "testBranch", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		logResultError := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Error", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` | ||||
| @@ -130,13 +149,22 @@ func TestCheckoutBranchStep(t *testing.T) { | ||||
| 				`{"d" : { "status" : "E" } }`, | ||||
| 				`{"d" : { "status" : "E" } }`, | ||||
| 				`{"d" : { "status" : "E" } }`, | ||||
| 				`{"d" : { "status" : "E" } }`, | ||||
| 			}, | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "checkoutBranch", | ||||
| 			FileNameStep: "checkoutBranch", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.EqualError(t, err, expectedErrorMessage) | ||||
| 	}) | ||||
| 	t.Run("Success case: checkout Branches from file config", func(t *testing.T) { | ||||
| @@ -183,9 +211,19 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "repositoriesTest.yml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "checkoutBranch", | ||||
| 			FileNameStep: "checkoutBranch", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.NoError(t, err) | ||||
| 	}) | ||||
| 	t.Run("Failure case: checkout Branches from empty file config", func(t *testing.T) { | ||||
| @@ -227,9 +265,19 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "repositoriesTest.yml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "checkoutBranch", | ||||
| 			FileNameStep: "checkoutBranch", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.EqualError(t, err, expectedErrorMessage) | ||||
| 	}) | ||||
| 	t.Run("Failure case: checkout Branches from wrong file config", func(t *testing.T) { | ||||
| @@ -276,9 +324,19 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "repositoriesTest.yml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "checkoutBranch", | ||||
| 			FileNameStep: "checkoutBranch", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.EqualError(t, err, expectedErrorMessage) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import ( | ||||
| 	"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" | ||||
| ) | ||||
| @@ -26,14 +27,23 @@ func abapEnvironmentCloneGitRepo(config abapEnvironmentCloneGitRepoOptions, _ *t | ||||
| 		Client:        &piperhttp.Client{}, | ||||
| 		PollIntervall: 5 * time.Second, | ||||
| 	} | ||||
|  | ||||
| 	var reports []piperutils.Path | ||||
| 	logOutputManager := abaputils.LogOutputManager{ | ||||
| 		LogOutput:    config.LogOutput, | ||||
| 		PiperStep:    "clone", | ||||
| 		FileNameStep: "clone", | ||||
| 		StepReports:  reports, | ||||
| 	} | ||||
|  | ||||
| 	// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end | ||||
| 	err := runAbapEnvironmentCloneGitRepo(&config, &autils, &apiManager) | ||||
| 	err := runAbapEnvironmentCloneGitRepo(&config, &autils, &apiManager, &logOutputManager) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runAbapEnvironmentCloneGitRepo(config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface) error { | ||||
| func runAbapEnvironmentCloneGitRepo(config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) error { | ||||
| 	// Mapping for options | ||||
| 	subOptions := convertCloneConfig(config) | ||||
|  | ||||
| @@ -55,19 +65,23 @@ func runAbapEnvironmentCloneGitRepo(config *abapEnvironmentCloneGitRepoOptions, | ||||
| 	connectionDetails.CertificateNames = config.CertificateNames | ||||
|  | ||||
| 	log.Entry().Infof("Start cloning %v repositories", len(repositories)) | ||||
|  | ||||
| 	for _, repo := range repositories { | ||||
|  | ||||
| 		cloneError := cloneSingleRepo(apiManager, connectionDetails, repo, config, com) | ||||
| 		cloneError := cloneSingleRepo(apiManager, connectionDetails, repo, config, com, logOutputManager) | ||||
| 		if cloneError != nil { | ||||
| 			return cloneError | ||||
| 		} | ||||
| 	} | ||||
| 	// Persist log archive | ||||
| 	abaputils.PersistArchiveLogsForPiperStep(logOutputManager) | ||||
|  | ||||
| 	abaputils.AddDefaultDashedLine(1) | ||||
| 	log.Entry().Info("All repositories were cloned successfully") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface, connectionDetails abaputils.ConnectionDetailsHTTP, repo abaputils.Repository, config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication) error { | ||||
| func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface, connectionDetails abaputils.ConnectionDetailsHTTP, repo abaputils.Repository, config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication, logOutputManager *abaputils.LogOutputManager) error { | ||||
|  | ||||
| 	// New API instance for each request | ||||
| 	// Triggering the Clone of the repository into the ABAP Environment system | ||||
| @@ -98,8 +112,9 @@ func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface, | ||||
| 		if errClone != nil { | ||||
| 			return errors.Wrapf(errClone, errorString) | ||||
| 		} | ||||
|  | ||||
| 		status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall()) | ||||
| 		// set correct filename for archive file | ||||
| 		logOutputManager.FileNameStep = "clone" | ||||
| 		status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall(), logOutputManager) | ||||
| 		if errorPollEntity != nil { | ||||
| 			return errors.Wrapf(errorPollEntity, errorString) | ||||
| 		} | ||||
| @@ -114,13 +129,13 @@ func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface, | ||||
| 		abaputils.AddDefaultDashedLine(2) | ||||
| 		var returnedError error | ||||
| 		if repo.Branch != "" && !(activeBranch == repo.Branch) { | ||||
| 			returnedError = runAbapEnvironmentCheckoutBranch(getCheckoutOptions(config, repo), com, apiManager) | ||||
| 			returnedError = runAbapEnvironmentCheckoutBranch(getCheckoutOptions(config, repo), com, apiManager, logOutputManager) | ||||
| 			abaputils.AddDefaultDashedLine(2) | ||||
| 			if returnedError != nil { | ||||
| 				return returnedError | ||||
| 			} | ||||
| 		} | ||||
| 		returnedError = runAbapEnvironmentPullGitRepo(getPullOptions(config, repo), com, apiManager) | ||||
| 		returnedError = runAbapEnvironmentPullGitRepo(getPullOptions(config, repo), com, apiManager, logOutputManager) | ||||
| 		return returnedError | ||||
| 	} | ||||
| 	return nil | ||||
| @@ -154,6 +169,7 @@ func getPullOptions(config *abapEnvironmentCloneGitRepoOptions, repo abaputils.R | ||||
| 		CfServiceInstance: config.CfServiceInstance, | ||||
| 		CfServiceKeyName:  config.CfServiceKeyName, | ||||
| 		CfSpace:           config.CfSpace, | ||||
| 		LogOutput:         config.LogOutput, | ||||
| 	} | ||||
| 	return &pullOptions | ||||
| } | ||||
|   | ||||
| @@ -25,6 +25,7 @@ type abapEnvironmentCloneGitRepoOptions struct { | ||||
| 	RepositoryName    string   `json:"repositoryName,omitempty"` | ||||
| 	BranchName        string   `json:"branchName,omitempty"` | ||||
| 	Host              string   `json:"host,omitempty"` | ||||
| 	LogOutput         string   `json:"logOutput,omitempty" validate:"possible-values=ZIP STANDARD"` | ||||
| 	CfAPIEndpoint     string   `json:"cfApiEndpoint,omitempty"` | ||||
| 	CfOrg             string   `json:"cfOrg,omitempty"` | ||||
| 	CfSpace           string   `json:"cfSpace,omitempty"` | ||||
| @@ -150,6 +151,7 @@ func addAbapEnvironmentCloneGitRepoFlags(cmd *cobra.Command, stepConfig *abapEnv | ||||
| 	cmd.Flags().StringVar(&stepConfig.RepositoryName, "repositoryName", os.Getenv("PIPER_repositoryName"), "Specifies a repository (Software Components) on the SAP BTP ABAP Environment system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.BranchName, "branchName", os.Getenv("PIPER_branchName"), "Specifies a branch of a repository (Software Components) on the SAP BTP ABAP Environment system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Host, "host", os.Getenv("PIPER_host"), "Specifies the host address of the SAP BTP ABAP Environment system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.LogOutput, "logOutput", `STANDARD`, "Specifies how the clone logs from the Manage Software Components App are displayed or saved") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfAPIEndpoint, "cfApiEndpoint", os.Getenv("PIPER_cfApiEndpoint"), "Cloud Foundry API Enpoint") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "Cloud Foundry target organization") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfSpace, "cfSpace", os.Getenv("PIPER_cfSpace"), "Cloud Foundry target space") | ||||
| @@ -283,6 +285,15 @@ func abapEnvironmentCloneGitRepoMetadata() config.StepData { | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_host"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "logOutput", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     `STANDARD`, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "cfApiEndpoint", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| @@ -75,6 +76,7 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "filename.yaml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` | ||||
| @@ -100,8 +102,16 @@ repositories: | ||||
| 			Token: "myToken", | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") | ||||
| 	}) | ||||
| @@ -123,6 +133,7 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			RepositoryName:    "testRepo1", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		logResultSuccess := `{"d": { "sc_name": "testRepo1", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` | ||||
| @@ -139,9 +150,16 @@ repositories: | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") | ||||
| 	}) | ||||
| @@ -164,21 +182,30 @@ repositories: | ||||
| 			Password:          "testPassword", | ||||
| 			RepositoryName:    "testRepo1", | ||||
| 			BranchName:        "testBranch1", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			BodyList: []string{ | ||||
| 				`{"d" : {} }`, | ||||
| 				`{"d" : {} }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 				`{"d" : { "sc_name" : "testRepo1", "avail_on_instance" : true, "active_branch": "testBranch1" } }`, | ||||
| 				`{"d" : [] }`, | ||||
| 				`{"d" : {} }`, | ||||
| 			}, | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "Clone of repository / software component 'testRepo1', branch 'testBranch1' failed on the ABAP system: Request to ABAP System not successful", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -224,6 +251,7 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "filename.yaml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		logResultError := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Error", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` | ||||
| @@ -239,8 +267,16 @@ repositories: | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "Clone of repository / software component '/DMO/REPO_A', branch 'branchA', commit 'ABCD1234' failed on the ABAP system: Request to ABAP System not successful", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -264,6 +300,7 @@ repositories: | ||||
| 			Password:          "testPassword", | ||||
| 			RepositoryName:    "testRepo1", | ||||
| 			BranchName:        "testBranch1", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| @@ -275,8 +312,16 @@ repositories: | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "Clone of repository / software component 'testRepo1', branch 'testBranch1' failed on the ABAP system: Request to ABAP System not successful", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -300,6 +345,7 @@ repositories: | ||||
| 			Password:          "testPassword", | ||||
| 			RepositoryName:    "testRepo1", | ||||
| 			BranchName:        "testBranch1", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| @@ -310,8 +356,16 @@ repositories: | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "Clone of repository / software component 'testRepo1', branch 'testBranch1' failed on the ABAP system: Request to ABAP System not successful", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -334,6 +388,7 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "filename.yaml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| @@ -344,8 +399,16 @@ repositories: | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "Could not read repositories: Could not find filename.yaml", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -371,6 +434,7 @@ repositories: | ||||
| 			Repositories:      "filename.yaml", | ||||
| 			RepositoryName:    "/DMO/REPO", | ||||
| 			BranchName:        "Branch", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		logResultError := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Error", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` | ||||
| @@ -385,8 +449,16 @@ repositories: | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "The provided configuration is not allowed: It is not allowed to configure the parameters `repositories`and `repositoryName` at the same time", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -412,6 +484,7 @@ func TestALreadyCloned(t *testing.T) { | ||||
| 			CfServiceKeyName:  "testServiceKey", | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` | ||||
| @@ -441,8 +514,16 @@ func TestALreadyCloned(t *testing.T) { | ||||
| 			CommitID: "abcd1234", | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := cloneSingleRepo(apiManager, autils.ReturnedConnectionDetailsHTTP, repo, &config, &autils) | ||||
| 		err := cloneSingleRepo(apiManager, autils.ReturnedConnectionDetailsHTTP, repo, &config, &autils, &logOutputManager) | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 	}) | ||||
|  | ||||
| @@ -464,6 +545,7 @@ func TestALreadyCloned(t *testing.T) { | ||||
| 			CfServiceKeyName:  "testServiceKey", | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` | ||||
| @@ -487,8 +569,16 @@ func TestALreadyCloned(t *testing.T) { | ||||
| 			CommitID: "abcd1234", | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "clone", | ||||
| 			FileNameStep: "clone", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := cloneSingleRepo(apiManager, autils.ReturnedConnectionDetailsHTTP, repo, &config, &autils) | ||||
| 		err := cloneSingleRepo(apiManager, autils.ReturnedConnectionDetailsHTTP, repo, &config, &autils, &logOutputManager) | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 	}) | ||||
|  | ||||
|   | ||||
| @@ -97,7 +97,14 @@ func createSingleTag(item abaputils.CreateTagBacklog, index int, con abaputils.C | ||||
| 		return errors.Wrapf(err, "Creation of Tag failed on the ABAP system") | ||||
| 	} | ||||
|  | ||||
| 	status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall()) | ||||
| 	logOutputManager := abaputils.LogOutputManager{ | ||||
| 		LogOutput:    "STANDARD", | ||||
| 		PiperStep:    "createTag", | ||||
| 		FileNameStep: "createTag", | ||||
| 		StepReports:  nil, | ||||
| 	} | ||||
|  | ||||
| 	status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall(), &logOutputManager) | ||||
|  | ||||
| 	if errorPollEntity == nil && status == "S" { | ||||
| 		log.Entry().Info("Created tag " + item.Tags[index].TagName + " for repository " + item.RepositoryName + " with commitID " + item.CommitID) | ||||
|   | ||||
| @@ -104,11 +104,11 @@ repositories: | ||||
| 		apiManager := &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentCreateTag(config, autils, apiManager) | ||||
|  | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		assert.Equal(t, 25, len(hook.Entries), "Expected a different number of entries") | ||||
| 		assert.Equal(t, `Created tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[12].Message, "Expected a different message") | ||||
| 		assert.Equal(t, `Created tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[18].Message, "Expected a different message") | ||||
| 		assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[24].Message, "Expected a different message") | ||||
| 		assert.Error(t, err, "Did expect error") | ||||
| 		assert.Equal(t, 18, len(hook.Entries), "Expected a different number of entries") | ||||
| 		assert.Equal(t, `Created tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[6].Message, "Expected a different message") | ||||
| 		assert.Equal(t, `NOT created: Tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[11].Message, "Expected a different message") | ||||
| 		assert.Equal(t, `NOT created: Tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[16].Message, "Expected a different message") | ||||
| 		hook.Reset() | ||||
| 	}) | ||||
|  | ||||
| @@ -179,12 +179,11 @@ repositories: | ||||
| 		apiManager := &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentCreateTag(config, autils, apiManager) | ||||
|  | ||||
| 		assert.Error(t, err, "Did expect error") | ||||
| 		assert.Equal(t, 40, len(hook.Entries), "Expected a different number of entries") | ||||
| 		assert.Equal(t, `NOT created: Tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[12].Message, "Expected a different message") | ||||
| 		assert.Equal(t, `NOT created: Tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[25].Message, "Expected a different message") | ||||
| 		assert.Equal(t, `NOT created: Tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[38].Message, "Expected a different message") | ||||
| 		assert.Equal(t, `At least one tag has not been created`, hook.AllEntries()[39].Message, "Expected a different message") | ||||
| 		assert.NoError(t, err, "Did expect error") | ||||
| 		assert.Equal(t, 21, len(hook.Entries), "Expected a different number of entries") | ||||
| 		assert.Equal(t, `Created tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[6].Message, "Expected a different message") | ||||
| 		assert.Equal(t, `Created tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[13].Message, "Expected a different message") | ||||
| 		assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[20].Message, "Expected a different message") | ||||
| 		hook.Reset() | ||||
|  | ||||
| 	}) | ||||
| @@ -232,8 +231,8 @@ func TestRunAbapEnvironmentCreateTagConfigurations(t *testing.T) { | ||||
| 		err := runAbapEnvironmentCreateTag(config, autils, apiManager) | ||||
|  | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		assert.Equal(t, 13, len(hook.Entries), "Expected a different number of entries") | ||||
| 		assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[12].Message, "Expected a different message") | ||||
| 		assert.Equal(t, 7, len(hook.Entries), "Expected a different number of entries") | ||||
| 		assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[6].Message, "Expected a different message") | ||||
| 		hook.Reset() | ||||
| 	}) | ||||
|  | ||||
| @@ -362,9 +361,9 @@ repositories: | ||||
| 		apiManager := &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentCreateTag(config, autils, apiManager) | ||||
|  | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		assert.Equal(t, 6, len(hook.Entries), "Expected a different number of entries") | ||||
| 		assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[5].Message, "Expected a different message") | ||||
| 		assert.Error(t, err, "Did expect error") | ||||
| 		assert.Equal(t, 8, len(hook.Entries), "Expected a different number of entries") | ||||
| 		assert.Equal(t, `NOT created: Tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[6].Message, "Expected a different message") | ||||
| 		hook.Reset() | ||||
|  | ||||
| 	}) | ||||
|   | ||||
| @@ -8,6 +8,7 @@ import ( | ||||
| 	"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" | ||||
| ) | ||||
| @@ -28,15 +29,22 @@ func abapEnvironmentPullGitRepo(options abapEnvironmentPullGitRepoOptions, _ *te | ||||
| 		Client:        &piperhttp.Client{}, | ||||
| 		PollIntervall: 5 * time.Second, | ||||
| 	} | ||||
| 	var reports []piperutils.Path | ||||
| 	logOutputManager := abaputils.LogOutputManager{ | ||||
| 		LogOutput:    options.LogOutput, | ||||
| 		PiperStep:    "pull", | ||||
| 		FileNameStep: "pull", | ||||
| 		StepReports:  reports, | ||||
| 	} | ||||
|  | ||||
| 	// error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end | ||||
| 	err := runAbapEnvironmentPullGitRepo(&options, &autils, &apiManager) | ||||
| 	err := runAbapEnvironmentPullGitRepo(&options, &autils, &apiManager, &logOutputManager) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runAbapEnvironmentPullGitRepo(options *abapEnvironmentPullGitRepoOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { | ||||
| func runAbapEnvironmentPullGitRepo(options *abapEnvironmentPullGitRepoOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { | ||||
|  | ||||
| 	subOptions := convertPullConfig(options) | ||||
|  | ||||
| @@ -52,21 +60,26 @@ func runAbapEnvironmentPullGitRepo(options *abapEnvironmentPullGitRepoOptions, c | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	repositories, err = abaputils.GetRepositories(&abaputils.RepositoriesConfig{RepositoryNames: options.RepositoryNames, Repositories: options.Repositories, RepositoryName: options.RepositoryName, CommitID: options.CommitID}, false) | ||||
| 	handleIgnoreCommit(repositories, options.IgnoreCommit) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	err = pullRepositories(repositories, connectionDetails, apiManager) | ||||
| 	err = pullRepositories(repositories, connectionDetails, apiManager, logOutputManager) | ||||
|  | ||||
| 	// Persist log archive | ||||
| 	abaputils.PersistArchiveLogsForPiperStep(logOutputManager) | ||||
|  | ||||
| 	return err | ||||
|  | ||||
| } | ||||
|  | ||||
| func pullRepositories(repositories []abaputils.Repository, pullConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { | ||||
| func pullRepositories(repositories []abaputils.Repository, pullConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { | ||||
| 	log.Entry().Infof("Start pulling %v repositories", len(repositories)) | ||||
| 	for _, repo := range repositories { | ||||
| 		err = handlePull(repo, pullConnectionDetails, apiManager) | ||||
| 		err = handlePull(repo, pullConnectionDetails, apiManager, logOutputManager) | ||||
| 		if err != nil { | ||||
| 			break | ||||
| 		} | ||||
| @@ -77,7 +90,7 @@ func pullRepositories(repositories []abaputils.Repository, pullConnectionDetails | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func handlePull(repo abaputils.Repository, con abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { | ||||
| func handlePull(repo abaputils.Repository, con abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { | ||||
|  | ||||
| 	logString := repo.GetPullLogString() | ||||
| 	errorString := "Pull of the " + logString + " failed on the ABAP system" | ||||
| @@ -96,8 +109,10 @@ func handlePull(repo abaputils.Repository, con abaputils.ConnectionDetailsHTTP, | ||||
| 		return errors.Wrapf(err, errorString) | ||||
| 	} | ||||
|  | ||||
| 	// set correct filename for archive file | ||||
| 	logOutputManager.FileNameStep = "pull" | ||||
| 	// Polling the status of the repository import on the ABAP Environment system | ||||
| 	status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall()) | ||||
| 	status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall(), logOutputManager) | ||||
| 	if errorPollEntity != nil { | ||||
| 		return errors.Wrapf(errorPollEntity, errorString) | ||||
| 	} | ||||
|   | ||||
| @@ -23,6 +23,7 @@ type abapEnvironmentPullGitRepoOptions struct { | ||||
| 	RepositoryName    string   `json:"repositoryName,omitempty"` | ||||
| 	CommitID          string   `json:"commitID,omitempty"` | ||||
| 	Host              string   `json:"host,omitempty"` | ||||
| 	LogOutput         string   `json:"logOutput,omitempty" validate:"possible-values=ZIP STANDARD"` | ||||
| 	CfAPIEndpoint     string   `json:"cfApiEndpoint,omitempty"` | ||||
| 	CfOrg             string   `json:"cfOrg,omitempty"` | ||||
| 	CfSpace           string   `json:"cfSpace,omitempty"` | ||||
| @@ -145,6 +146,7 @@ func addAbapEnvironmentPullGitRepoFlags(cmd *cobra.Command, stepConfig *abapEnvi | ||||
| 	cmd.Flags().StringVar(&stepConfig.RepositoryName, "repositoryName", os.Getenv("PIPER_repositoryName"), "Specifies a repository (Software Component) on the SAP BTP ABAP Environment system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CommitID, "commitID", os.Getenv("PIPER_commitID"), "Specifies a commitID of the repository, configured via \"repositoryName\" on the SAP BTP ABAP Environment system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Host, "host", os.Getenv("PIPER_host"), "Specifies the host address of the SAP BTP ABAP Environment system") | ||||
| 	cmd.Flags().StringVar(&stepConfig.LogOutput, "logOutput", `STANDARD`, "Specifies how the clone logs from the Manage Software Components App are displayed or saved") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfAPIEndpoint, "cfApiEndpoint", os.Getenv("PIPER_cfApiEndpoint"), "Cloud Foundry API Enpoint") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "Cloud Foundry target organization") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfSpace, "cfSpace", os.Getenv("PIPER_cfSpace"), "Cloud Foundry target space") | ||||
| @@ -246,6 +248,15 @@ func abapEnvironmentPullGitRepoMetadata() config.StepData { | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_host"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "logOutput", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     `STANDARD`, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "cfApiEndpoint", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| @@ -53,6 +54,7 @@ func TestPullStep(t *testing.T) { | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			RepositoryNames:   []string{"testRepo1"}, | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` | ||||
| @@ -70,7 +72,16 @@ func TestPullStep(t *testing.T) { | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "pull", | ||||
| 			FileNameStep: "pull", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.NoError(t, err, "Did not expect error") | ||||
| 		assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") | ||||
| 	}) | ||||
| @@ -96,8 +107,16 @@ func TestPullStep(t *testing.T) { | ||||
|  | ||||
| 		config := abapEnvironmentPullGitRepoOptions{} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    "STANDARD", | ||||
| 			PiperStep:    "pull", | ||||
| 			FileNameStep: "pull", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.Equal(t, expectedErrorMessage, err.Error(), "Different error message expected") | ||||
| 	}) | ||||
|  | ||||
| @@ -146,9 +165,19 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "repositoriesTest.yml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "pull", | ||||
| 			FileNameStep: "pull", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.NoError(t, err) | ||||
| 	}) | ||||
|  | ||||
| @@ -189,6 +218,7 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "filename.yaml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			BodyList: []string{ | ||||
| @@ -198,13 +228,22 @@ repositories: | ||||
| 				`{"d" : { "status" : "E" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 			}, | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "pull", | ||||
| 			FileNameStep: "pull", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "Pull of the repository / software component '/DMO/REPO_A', commit 'ABCD1234' failed on the ABAP system", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -248,6 +287,7 @@ repositories: | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "filename.yaml", | ||||
| 			IgnoreCommit:      true, | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			BodyList: []string{ | ||||
| @@ -257,13 +297,22 @@ repositories: | ||||
| 				`{"d" : { "status" : "E" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 			}, | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "pull", | ||||
| 			FileNameStep: "pull", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "Pull of the repository / software component '/DMO/REPO_A', tag 'v-1.0.1-build-0001' failed on the ABAP system", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -288,6 +337,7 @@ repositories: | ||||
| 			RepositoryName:    "/DMO/SWC", | ||||
| 			CommitID:          "123456", | ||||
| 			IgnoreCommit:      false, | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			BodyList: []string{ | ||||
| @@ -297,13 +347,22 @@ repositories: | ||||
| 				`{"d" : { "status" : "E" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 			}, | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "pull", | ||||
| 			FileNameStep: "pull", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "Pull of the repository / software component '/DMO/SWC', commit '123456' failed on the ABAP system", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -327,6 +386,7 @@ repositories: | ||||
| 			Password:          "testPassword", | ||||
| 			RepositoryName:    "/DMO/SWC", | ||||
| 			IgnoreCommit:      false, | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			BodyList: []string{ | ||||
| @@ -336,13 +396,22 @@ repositories: | ||||
| 				`{"d" : { "status" : "E" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 				`{"d" : { "status" : "R" } }`, | ||||
| 			}, | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "pull", | ||||
| 			FileNameStep: "pull", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) | ||||
| 		err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		if assert.Error(t, err, "Expected error") { | ||||
| 			assert.Equal(t, "Pull of the repository / software component '/DMO/SWC' failed on the ABAP system", err.Error(), "Expected different error message") | ||||
| 		} | ||||
| @@ -387,9 +456,19 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "repositoriesTest.yml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "pull", | ||||
| 			FileNameStep: "pull", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.EqualError(t, err, expectedErrorMessage) | ||||
| 	}) | ||||
|  | ||||
| @@ -437,9 +516,19 @@ repositories: | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			Repositories:      "repositoriesTest.yml", | ||||
| 			LogOutput:         "STANDARD", | ||||
| 		} | ||||
|  | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := abaputils.LogOutputManager{ | ||||
| 			LogOutput:    config.LogOutput, | ||||
| 			PiperStep:    "pull", | ||||
| 			FileNameStep: "pull", | ||||
| 			StepReports:  reports, | ||||
| 		} | ||||
|  | ||||
| 		apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) | ||||
| 		err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) | ||||
| 		assert.EqualError(t, err, expectedErrorMessage) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -2,12 +2,14 @@ package abaputils | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| 	"sort" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| @@ -15,13 +17,37 @@ const numberOfEntriesPerPage = 100000 | ||||
| const logOutputStatusLength = 10 | ||||
| const logOutputTimestampLength = 29 | ||||
|  | ||||
| // Specifies which output option is used for logs | ||||
| type LogOutputManager struct { | ||||
| 	LogOutput    string | ||||
| 	PiperStep    string | ||||
| 	FileNameStep string | ||||
| 	StepReports  []piperutils.Path | ||||
| } | ||||
|  | ||||
| func PersistArchiveLogsForPiperStep(logOutputManager *LogOutputManager) { | ||||
| 	fileUtils := piperutils.Files{} | ||||
| 	switch logOutputManager.PiperStep { | ||||
| 	case "clone": | ||||
| 		piperutils.PersistReportsAndLinks("abapEnvironmentCloneGitRepo", "", fileUtils, logOutputManager.StepReports, nil) | ||||
| 	case "pull": | ||||
| 		piperutils.PersistReportsAndLinks("abapEnvironmentPullGitRepo", "", fileUtils, logOutputManager.StepReports, nil) | ||||
| 	case "checkoutBranch": | ||||
| 		piperutils.PersistReportsAndLinks("abapEnvironmentCheckoutBranch", "", fileUtils, logOutputManager.StepReports, nil) | ||||
| 	default: | ||||
| 		log.Entry().Info("Cannot save log archive because no piper step was defined.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // PollEntity periodically polls the action entity to get the status. Check if the import is still running | ||||
| func PollEntity(api SoftwareComponentApiInterface, pollIntervall time.Duration) (string, error) { | ||||
| func PollEntity(api SoftwareComponentApiInterface, pollIntervall time.Duration, logOutputManager *LogOutputManager) (string, error) { | ||||
|  | ||||
| 	log.Entry().Info("Start polling the status...") | ||||
| 	var statusCode string = "R" | ||||
| 	var err error | ||||
|  | ||||
| 	api.initialRequest() | ||||
|  | ||||
| 	for { | ||||
| 		// pullEntity, responseStatus, err := api.GetStatus(failureMessageClonePull+repositoryName, connectionDetails, client) | ||||
| 		statusCode, err = api.GetAction() | ||||
| @@ -31,7 +57,7 @@ func PollEntity(api SoftwareComponentApiInterface, pollIntervall time.Duration) | ||||
|  | ||||
| 		if statusCode != "R" && statusCode != "Q" { | ||||
|  | ||||
| 			PrintLogs(api) | ||||
| 			PrintLogs(api, logOutputManager) | ||||
| 			break | ||||
| 		} | ||||
| 		time.Sleep(pollIntervall) | ||||
| @@ -39,7 +65,7 @@ func PollEntity(api SoftwareComponentApiInterface, pollIntervall time.Duration) | ||||
| 	return statusCode, nil | ||||
| } | ||||
|  | ||||
| func PrintLogs(api SoftwareComponentApiInterface) { | ||||
| func PrintLogs(api SoftwareComponentApiInterface, logOutputManager *LogOutputManager) { | ||||
|  | ||||
| 	// Get Execution Logs | ||||
| 	executionLogs, err := api.GetExecutionLog() | ||||
| @@ -47,11 +73,7 @@ func PrintLogs(api SoftwareComponentApiInterface) { | ||||
| 		printExecutionLogs(executionLogs) | ||||
| 	} | ||||
|  | ||||
| 	results, err := api.GetLogOverview() | ||||
| 	if err != nil || len(results) == 0 { | ||||
| 		// return if no logs are available | ||||
| 		return | ||||
| 	} | ||||
| 	results, _ := api.GetLogOverview() | ||||
|  | ||||
| 	// Sort logs | ||||
| 	sort.SliceStable(results, func(i, j int) bool { | ||||
| @@ -60,13 +82,31 @@ func PrintLogs(api SoftwareComponentApiInterface) { | ||||
|  | ||||
| 	printOverview(results, api) | ||||
|  | ||||
| 	// Print Details | ||||
| 	for _, logEntryForDetails := range results { | ||||
| 		printLog(logEntryForDetails, api) | ||||
| 	} | ||||
| 	AddDefaultDashedLine(1) | ||||
| 	if logOutputManager.LogOutput == "ZIP" { | ||||
| 		// get zip file as byte array | ||||
| 		zipfile, err := api.GetLogArchive() | ||||
| 		// Saving logs in file and adding to piperutils to archive file | ||||
| 		if err == nil { | ||||
| 			fileName := "LogArchive-" + logOutputManager.FileNameStep + "-" + strings.Replace(api.getRepositoryName(), "/", "_", -1) + "-" + api.getUUID() + "_" + time.Now().Format("2006-01-02T15:04:05") + ".zip" | ||||
|  | ||||
| 			err = os.WriteFile(fileName, zipfile, 0o644) | ||||
|  | ||||
| 			if err == nil { | ||||
| 				log.Entry().Infof("Writing %s file was successful", fileName) | ||||
| 				logOutputManager.StepReports = append(logOutputManager.StepReports, piperutils.Path{Target: fileName, Name: "Log_Archive_" + api.getUUID(), Mandatory: true}) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 	} else { | ||||
| 		// Print Details | ||||
| 		if len(results) != 0 { | ||||
| 			for _, logEntryForDetails := range results { | ||||
| 				printLog(logEntryForDetails, api) | ||||
| 			} | ||||
| 		} | ||||
| 		AddDefaultDashedLine(1) | ||||
| 	} | ||||
|  | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func printExecutionLogs(executionLogs ExecutionLog) { | ||||
| @@ -82,6 +122,10 @@ func printExecutionLogs(executionLogs ExecutionLog) { | ||||
|  | ||||
| func printOverview(results []LogResultsV2, api SoftwareComponentApiInterface) { | ||||
|  | ||||
| 	if len(results) == 0 { | ||||
| 		return | ||||
| 	} | ||||
|  | ||||
| 	logOutputPhaseLength, logOutputLineLength := calculateLenghts(results) | ||||
|  | ||||
| 	log.Entry().Infof("\n") | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import ( | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/piperutils" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| @@ -63,7 +64,14 @@ func TestPollEntity(t *testing.T) { | ||||
| 		repo := Repository{Name: "testRepo1"} | ||||
| 		api, _ := swcManager.GetAPI(con, repo) | ||||
|  | ||||
| 		status, _ := PollEntity(api, 0) | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := LogOutputManager{ | ||||
| 			LogOutput:   "STANDARD", | ||||
| 			PiperStep:   "pull", | ||||
| 			StepReports: reports, | ||||
| 		} | ||||
|  | ||||
| 		status, _ := PollEntity(api, 0, &logOutputManager) | ||||
| 		assert.Equal(t, "S", status) | ||||
| 		assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") | ||||
| 	}) | ||||
| @@ -95,7 +103,14 @@ func TestPollEntity(t *testing.T) { | ||||
| 		repo := Repository{Name: "testRepo1"} | ||||
| 		api, _ := swcManager.GetAPI(con, repo) | ||||
|  | ||||
| 		status, _ := PollEntity(api, 0) | ||||
| 		var reports []piperutils.Path | ||||
| 		logOutputManager := LogOutputManager{ | ||||
| 			LogOutput:   "STANDARD", | ||||
| 			PiperStep:   "pull", | ||||
| 			StepReports: reports, | ||||
| 		} | ||||
|  | ||||
| 		status, _ := PollEntity(api, 0, &logOutputManager) | ||||
| 		assert.Equal(t, "E", status) | ||||
| 		assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") | ||||
| 	}) | ||||
|   | ||||
| @@ -225,6 +225,10 @@ func (api *SAP_COM_0510) GetAction() (string, error) { | ||||
| 	return abapStatusCode, nil | ||||
| } | ||||
|  | ||||
| func (api *SAP_COM_0510) getRepositoryName() string { | ||||
| 	return api.repository.Name | ||||
| } | ||||
|  | ||||
| func (api *SAP_COM_0510) GetRepository() (bool, string, error, bool) { | ||||
|  | ||||
| 	if api.repository.Name == "" { | ||||
| @@ -404,3 +408,8 @@ func (api *SAP_COM_0510) ConvertTime(logTimeStamp string) time.Time { | ||||
| func (api *SAP_COM_0510) UpdateRepoWithBYOGCredentials(byogAuthMethod string, byogUsername string, byogPassword string) { | ||||
| 	panic("UpdateRepoWithBYOGCredentials cannot be used in SAP_COM_0510") | ||||
| } | ||||
|  | ||||
| // Dummy implementation of the "optional" method LogArchive (only used in SAP_COM_0948) | ||||
| func (api *SAP_COM_0510) GetLogArchive() (result []byte, err error) { | ||||
| 	panic("GetLogArchive cannot be used in SAP_COM_0510") | ||||
| } | ||||
|   | ||||
| @@ -239,6 +239,10 @@ func (api *SAP_COM_0948) GetAction() (string, error) { | ||||
| 	return abapStatusCode, nil | ||||
| } | ||||
|  | ||||
| func (api *SAP_COM_0948) getRepositoryName() string { | ||||
| 	return api.repository.Name | ||||
| } | ||||
|  | ||||
| func (api *SAP_COM_0948) GetRepository() (bool, string, error, bool) { | ||||
|  | ||||
| 	if api.repository.Name == "" { | ||||
| @@ -306,6 +310,28 @@ func (api *SAP_COM_0948) Clone() error { | ||||
|  | ||||
| } | ||||
|  | ||||
| func (api *SAP_COM_0948) GetLogArchive() (result []byte, err error) { | ||||
|  | ||||
| 	connectionDetails := api.con | ||||
| 	connectionDetails.URL = api.con.URL + api.path + "/LogArchive/" + api.getUUID() + "/download" | ||||
| 	resp, err := GetHTTPResponse("GET", connectionDetails, nil, api.client) | ||||
| 	if err != nil { | ||||
| 		log.SetErrorCategory(log.ErrorInfrastructure) | ||||
| 		_, err = handleHTTPError(resp, err, api.failureMessage, connectionDetails) | ||||
| 	} | ||||
|  | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	if resp.StatusCode != http.StatusOK { | ||||
| 		fmt.Println("Error: HTTP Status", resp.StatusCode) | ||||
| 		return nil, resp.Request.Context().Err() | ||||
| 	} | ||||
|  | ||||
| 	body, err := io.ReadAll(resp.Body) | ||||
|  | ||||
| 	return body, err | ||||
| } | ||||
|  | ||||
| func (api *SAP_COM_0948) triggerRequest(cloneConnectionDetails ConnectionDetailsHTTP, jsonBody []byte) error { | ||||
| 	var err error | ||||
| 	var body ActionEntity | ||||
|   | ||||
| @@ -573,3 +573,25 @@ func TestGetExecutionLog(t *testing.T) { | ||||
| 		assert.Equal(t, "First log entry", results.Value[0].Descr) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func TestGetLogArchive(t *testing.T) { | ||||
| 	t.Run("Test Get Log Archive Success", func(t *testing.T) { | ||||
|  | ||||
| 		client := &ClientMock{ | ||||
| 			BodyList: []string{ | ||||
| 				`{ zip content from log archive endpoint }`, | ||||
| 				``, | ||||
| 			}, | ||||
| 			Token:      "myToken", | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		apiManager := &SoftwareComponentApiManager{Client: client} | ||||
|  | ||||
| 		api, _ := apiManager.GetAPI(conTest0948, Repository{Name: "/DMO/REPO"}) | ||||
|  | ||||
| 		results, errAction := api.GetLogArchive() | ||||
| 		assert.NoError(t, errAction) | ||||
| 		assert.NotEmpty(t, results) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -59,6 +59,7 @@ type SoftwareComponentApiInterface interface { | ||||
| 	setSleepTimeConfig(timeUnit time.Duration, maxSleepTime time.Duration) | ||||
| 	getSleepTime(n int) (time.Duration, error) | ||||
| 	getUUID() string | ||||
| 	getRepositoryName() string | ||||
| 	GetRepository() (bool, string, error, bool) | ||||
| 	Clone() error | ||||
| 	Pull() error | ||||
| @@ -69,6 +70,7 @@ type SoftwareComponentApiInterface interface { | ||||
| 	GetLogProtocol(LogResultsV2, int) (result []LogProtocol, count int, err error) | ||||
| 	ConvertTime(logTimeStamp string) time.Time | ||||
| 	GetExecutionLog() (ExecutionLog, error) | ||||
| 	GetLogArchive() (result []byte, err error) | ||||
| 	UpdateRepoWithBYOGCredentials(string, string, string) | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -19,6 +19,7 @@ stages: | ||||
|     cfServiceKeyConfig: '{"scenario_id":"SAP_COM_0948","type":"basic"}' | ||||
|     cfAsync: false | ||||
|     ordinal: 30 | ||||
|     logOutput: ZIP | ||||
|  | ||||
|   'ATC': | ||||
|     ordinal: 40 | ||||
|   | ||||
| @@ -75,6 +75,17 @@ spec: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|       - name: logOutput | ||||
|         type: string | ||||
|         description: Specifies how the clone logs from the Manage Software Components App are displayed or saved | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         possibleValues: | ||||
|           - ZIP | ||||
|           - STANDARD | ||||
|         default: STANDARD | ||||
|       - name: cfApiEndpoint | ||||
|         type: string | ||||
|         description: Cloud Foundry API Enpoint | ||||
|   | ||||
| @@ -118,6 +118,17 @@ spec: | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|       - name: logOutput | ||||
|         type: string | ||||
|         description: Specifies how the clone logs from the Manage Software Components App are displayed or saved | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         possibleValues: | ||||
|           - ZIP | ||||
|           - STANDARD | ||||
|         default: STANDARD | ||||
|       - name: cfApiEndpoint | ||||
|         type: string | ||||
|         description: Cloud Foundry API Enpoint | ||||
|   | ||||
| @@ -82,6 +82,17 @@ spec: | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|       - name: logOutput | ||||
|         type: string | ||||
|         description: Specifies how the clone logs from the Manage Software Components App are displayed or saved | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         possibleValues: | ||||
|           - ZIP | ||||
|           - STANDARD | ||||
|         default: STANDARD | ||||
|       - name: cfApiEndpoint | ||||
|         type: string | ||||
|         description: Cloud Foundry API Enpoint | ||||
|   | ||||
		Reference in New Issue
	
	Block a user