From fffa2d050e9b299f7e98abb3cc53c9e273d2b2fd Mon Sep 17 00:00:00 2001 From: Maayan Hadasi <60384172+mguetta1@users.noreply.github.com> Date: Wed, 6 Dec 2023 20:56:41 +0200 Subject: [PATCH] [RFR] Ginkgo test: export applications as tasks to Jira (#56) * Adding new TC: export applications to Jira Signed-off-by: Maayan Hadasi * Using conf variable in utils Signed-off-by: Maayan Hadasi --------- Signed-off-by: Maayan Hadasi --- data/migrationwave_data.go | 8 +++ e2e/jiraintegration/jira_connection.go | 53 ++++------------- e2e/migrationwave/export.go | 81 ++++++++++++++++++++++++++ go_konveyor_tests_suite_test.go | 1 + hack/uniq/name.go | 5 ++ utils/jira_utils.go | 81 ++++++++++++++++++++++++++ utils/pkg.go | 20 +++++-- 7 files changed, 200 insertions(+), 49 deletions(-) create mode 100644 data/migrationwave_data.go create mode 100644 e2e/migrationwave/export.go create mode 100644 utils/jira_utils.go diff --git a/data/migrationwave_data.go b/data/migrationwave_data.go new file mode 100644 index 00000000..f68a71a4 --- /dev/null +++ b/data/migrationwave_data.go @@ -0,0 +1,8 @@ +package data + +type ExportApplicationsCase struct { + JiraInstance JiraInstanceTC + NumOfApps int + TicketKind string + TicketParent string +} diff --git a/e2e/jiraintegration/jira_connection.go b/e2e/jiraintegration/jira_connection.go index 80a062e4..20cbeee1 100644 --- a/e2e/jiraintegration/jira_connection.go +++ b/e2e/jiraintegration/jira_connection.go @@ -2,66 +2,33 @@ package jiraintegration import ( "strconv" - "time" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - . "github.com/konveyor/go-konveyor-tests/config" - . "github.com/konveyor/go-konveyor-tests/utils" + "github.com/konveyor/go-konveyor-tests/config" "github.com/konveyor/go-konveyor-tests/data" - "github.com/konveyor/go-konveyor-tests/hack/uniq" + "github.com/konveyor/go-konveyor-tests/utils" "github.com/konveyor/tackle2-hub/api" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" ) var _ = Describe("Jira connection", func() { var jiraIdentity api.Identity - var jiraInstance api.Tracker + var jiraInstance utils.Jira AfterEach(func() { // Resources cleanup // Delete tracker instance and the associated identity after - if keep, _ := strconv.ParseBool(Config.KEEP); keep { + if keep, _ := strconv.ParseBool(config.Config.KEEP); keep { return } - Expect(Tracker.Delete(jiraInstance.ID)).To(Succeed()) - Expect(Identity.Delete(jiraIdentity.ID)).To(Succeed()) + Expect(utils.Tracker.Delete(jiraInstance.ID)).To(Succeed()) + Expect(utils.Identity.Delete(jiraIdentity.ID)).To(Succeed()) }) DescribeTable("", func(testCase data.JiraInstanceTC) { - By("Create credential") - jiraIdentity = testCase.Identity - uniq.IdentityName(&jiraIdentity) - err := Identity.Create(&jiraIdentity) - Expect(err).NotTo(HaveOccurred()) - - By("Create Jira instance and associate credential") - jiraInstance = api.Tracker{ - URL: testCase.JiraUrl, - Kind: testCase.JiraKind, - Identity: api.Ref{ - ID: jiraIdentity.ID, - Name: jiraIdentity.Name, - }, - } - uniq.TrackerName(&jiraInstance) - err = Tracker.Create(&jiraInstance) - Expect(err).NotTo(HaveOccurred()) - - // Wait for connection succeeded - var jira *api.Tracker - var retry, _ = strconv.Atoi(Config.RETRY_NUM) - for i := 0; i < retry; i++ { - jira, err = Tracker.Get(jiraInstance.ID) - if err != nil || jira.Connected { - break - } - time.Sleep(5 * time.Second) - } - Expect(jira.Connected).To(BeTrue()) - + // Create Jira instance + jiraIdentity, jiraInstance = utils.CreateJiraInstance(testCase) }, Entry("Jira cloud", data.JiraCloud), Entry("Jira server with basic auth", data.JiraServer), diff --git a/e2e/migrationwave/export.go b/e2e/migrationwave/export.go new file mode 100644 index 00000000..76bbf1db --- /dev/null +++ b/e2e/migrationwave/export.go @@ -0,0 +1,81 @@ +package migrationwave + +import ( + "strconv" + "time" + + "github.com/konveyor/go-konveyor-tests/config" + "github.com/konveyor/go-konveyor-tests/data" + "github.com/konveyor/go-konveyor-tests/hack/uniq" + "github.com/konveyor/go-konveyor-tests/utils" + "github.com/konveyor/tackle2-hub/api" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var ( + jiraInstance utils.Jira + jiraIdentity api.Identity + migrationWave api.MigrationWave + issueIds []string + appsToExport []api.Application +) + +var _ = Describe("Export applications", func() { + AfterEach(func() { + // Resources cleanup + if keep, _ := strconv.ParseBool(config.Config.KEEP); keep { + return + } + Expect(utils.Tracker.Delete(jiraInstance.ID)).To(Succeed()) + Expect(utils.Identity.Delete(jiraIdentity.ID)).To(Succeed()) + Expect(utils.MigrationWave.Delete((migrationWave.ID))).To(Succeed()) /* Associated api.Ticket objects are removed as well */ + jiraInstance.DeleteJiraIssues(issueIds) + utils.DeleteApplicationsBySlice(appsToExport) + }) + + DescribeTable("", + func(testCase data.ExportApplicationsCase) { + appsToExport = utils.CreateMultipleApplications(testCase.NumOfApps) + By("Create migration wave") + uniq.MigrationWaveName(&migrationWave) + err := utils.MigrationWave.Create(&migrationWave) + Expect(err).NotTo(HaveOccurred()) + + By("Manage applications") + for i := 0; i < len(appsToExport); i++ { + migrationWave.Applications = append(migrationWave.Applications, api.Ref{ID: appsToExport[i].ID, Name: appsToExport[i].Name}) + } + err = utils.MigrationWave.Update(&migrationWave) + Expect(err).NotTo(HaveOccurred()) + + By("Create Jira instance") + jiraIdentity, jiraInstance = utils.CreateJiraInstance(testCase.JiraInstance) + + By("Check ticket was created") + for i := 0; i < len(appsToExport); i++ { + ticket := api.Ticket{Kind: testCase.TicketKind, Parent: testCase.TicketParent, Application: api.Ref{ID: appsToExport[i].ID}, + Tracker: api.Ref{ID: jiraInstance.ID}} + utils.Ticket.Create(&ticket) + + // Wait for reference field to be populated + var got *api.Ticket + var retry, _ = strconv.Atoi(config.Config.RETRY_NUM) + for i := 0; i < retry; i++ { + got, err = utils.Ticket.Get(ticket.ID) + if err != nil || got.Reference != "" { + break + } + time.Sleep(5 * time.Second) + } + Expect(got.Reference).NotTo(BeEmpty()) + issueIds = append(issueIds, got.Reference) + } + + }, + Entry("Export applications as a task", data.ExportApplicationsCase{ + JiraInstance: data.JiraCloud, + NumOfApps: 3, + TicketKind: "10007", /* Task issuetypeId */ + TicketParent: "10001" /* mta_integration projectId */})) +}) diff --git a/go_konveyor_tests_suite_test.go b/go_konveyor_tests_suite_test.go index 95a6c90c..4c3367d8 100644 --- a/go_konveyor_tests_suite_test.go +++ b/go_konveyor_tests_suite_test.go @@ -5,6 +5,7 @@ import ( _ "github.com/konveyor/go-konveyor-tests/e2e/jiraintegration" _ "github.com/konveyor/go-konveyor-tests/e2e/metrics" + _ "github.com/konveyor/go-konveyor-tests/e2e/migrationwave" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" ) diff --git a/hack/uniq/name.go b/hack/uniq/name.go index a8d4ec28..901b2b8d 100644 --- a/hack/uniq/name.go +++ b/hack/uniq/name.go @@ -39,3 +39,8 @@ func IdentityName(r *api.Identity) { func TrackerName(r *api.Tracker) { r.Name = fmt.Sprint(r.Kind, "-", RandString(5)) } + +// MigrationWaveName returns random MigrationWave Name +func MigrationWaveName(r *api.MigrationWave) { + r.Name = fmt.Sprint( "migrationwave-", RandString(5)) +} diff --git a/utils/jira_utils.go b/utils/jira_utils.go new file mode 100644 index 00000000..39e3e3fb --- /dev/null +++ b/utils/jira_utils.go @@ -0,0 +1,81 @@ +package utils + +import ( + "encoding/base64" + "net/http" + "strconv" + "time" + + "github.com/konveyor/go-konveyor-tests/data" + "github.com/konveyor/go-konveyor-tests/hack/uniq" + "github.com/konveyor/tackle2-hub/api" + "github.com/onsi/gomega" +) + +type Jira api.Tracker + +func CreateJiraInstance(data data.JiraInstanceTC) (api.Identity, Jira) { + jiraIdentity := data.Identity + uniq.IdentityName(&jiraIdentity) + err := Identity.Create(&jiraIdentity) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + jiraInstance := Jira{ + URL: data.JiraUrl, + Kind: data.JiraKind, + Identity: api.Ref{ + ID: jiraIdentity.ID, + Name: jiraIdentity.Name, + }, + } + uniq.TrackerName((*api.Tracker)(&jiraInstance)) + err = Tracker.Create((*api.Tracker)(&jiraInstance)) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + // Wait for connection succeeded + var jira *api.Tracker + var retry, _ = strconv.Atoi(conf.RETRY_NUM) + for i := 0; i < retry; i++ { + jira, err = Tracker.Get(jiraInstance.ID) + if err != nil || jira.Connected { + break + } + time.Sleep(5 * time.Second) + } + gomega.Expect(jira.Connected).To(gomega.BeTrue()) + + return jiraIdentity, jiraInstance +} + +func (r *Jira) DeleteJiraIssues(issues []string) { + for i := 0; i < len(issues); i++ { + url := conf.JIRA_CLOUD_URL + "/rest/api/3/issue/" + issues[i] + r.sendJiraRequest(url, "DELETE") + } +} + +func (r *Jira) sendJiraRequest(url string, method string) { + // Create a basic authentication string + basicAuth := "Basic " + + base64.StdEncoding.EncodeToString([]byte(conf.JIRA_CLOUD_USERNAME+":"+conf.JIRA_CLOUD_PASSWORD)) + + // Create a bearer authentication string + bearerAuth := "Bearer " + conf.JIRA_CLOUD_PASSWORD + + // Create a request + request, _ := http.NewRequest(method, url, nil) + + // Set the authorization header + request.Header.Set("Authorization", basicAuth) + if r.Kind == "on-permise" { + request.Header.Set("Authorization", bearerAuth) + } + + // Make the request + client := http.Client{} + response, err := client.Do(request) + gomega.Expect(err).NotTo(gomega.HaveOccurred()) + + // Ensure that the response body is closed when the function returns + defer response.Body.Close() +} diff --git a/utils/pkg.go b/utils/pkg.go index 5492008b..58c28c87 100644 --- a/utils/pkg.go +++ b/utils/pkg.go @@ -2,20 +2,26 @@ package utils import ( "github.com/jortel/go-utils/logr" + "github.com/konveyor/go-konveyor-tests/config" "github.com/konveyor/tackle2-hub/binding" "github.com/konveyor/tackle2-hub/test/api/client" ) var ( - Client *binding.Client - RichClient *binding.RichClient - Application binding.Application - Tracker binding.Tracker - Identity binding.Identity - Log = logr.WithName("test") + conf config.Configuration + Log = logr.WithName("test") + Client *binding.Client + RichClient *binding.RichClient + Application binding.Application + Tracker binding.Tracker + Identity binding.Identity + MigrationWave binding.MigrationWave + Ticket binding.Ticket ) func init() { + conf = config.Config + // Prepare RichClient and login to Hub API (configured from env variables). RichClient = client.PrepareRichClient() @@ -29,4 +35,6 @@ func init() { Tracker = RichClient.Tracker Identity = RichClient.Identity + MigrationWave = RichClient.MigrationWave + Ticket = RichClient.Ticket }