From 0ce61f58b4fb6cc34a8f54735670d186066f98a5 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Tue, 13 Jun 2023 08:08:43 +0530 Subject: [PATCH 01/20] add csv import test Signed-off-by: Yash Khare --- test/api/importCSV/api_test.go | 23 +++++++++ test/api/importCSV/pkg.go | 19 +++++++ test/api/importCSV/samples.go | 49 +++++++++++++++++++ .../importCSV/template_application_import.csv | 6 +++ 4 files changed, 97 insertions(+) create mode 100644 test/api/importCSV/api_test.go create mode 100644 test/api/importCSV/pkg.go create mode 100644 test/api/importCSV/samples.go create mode 100644 test/api/importCSV/template_application_import.csv diff --git a/test/api/importCSV/api_test.go b/test/api/importCSV/api_test.go new file mode 100644 index 000000000..68707f379 --- /dev/null +++ b/test/api/importCSV/api_test.go @@ -0,0 +1,23 @@ +package importCSV + +import ( + "testing" + + "github.com/konveyor/tackle2-hub/api" +) + +func TestImportCRUD(t *testing.T) { + for _, r := range Samples { + t.Run("CSV_Import", func(t *testing.T) { + + // Upload CSV. + api.ImportHandler.UploadCSV() // need to work on this how to fetch files(use RichClient.Client) + + // Get. + err := Client.Get(r.fileName, r.ExpectedApplications) // Client.Get() accepts a path need to figure out the path and the object + if err != nil { + t.Errorf(err.Error()) + } + }) + } +} diff --git a/test/api/importCSV/pkg.go b/test/api/importCSV/pkg.go new file mode 100644 index 000000000..a19657c83 --- /dev/null +++ b/test/api/importCSV/pkg.go @@ -0,0 +1,19 @@ +package importCSV + +import ( + "github.com/konveyor/tackle2-hub/binding" + "github.com/konveyor/tackle2-hub/test/api/client" +) + +var ( + RichClient *binding.RichClient + Client *binding.Client +) + +func init() { + // Prepare RichClient and login to Hub API (configured from env variables). + RichClient = client.PrepareRichClient() + + // Access REST client directly + Client = RichClient.Client() +} diff --git a/test/api/importCSV/samples.go b/test/api/importCSV/samples.go new file mode 100644 index 000000000..0e79070e4 --- /dev/null +++ b/test/api/importCSV/samples.go @@ -0,0 +1,49 @@ +package importCSV + +import ( + "github.com/konveyor/tackle2-hub/api" +) + +type TestCase struct { + fileName string + ExpectedApplications []api.Application + ExpectedDependencies []api.Dependency +} + +var ( + Applications = []api.Application{ + { + Name: "Gateway", + Description: "Gateway application", + }, + { + Name: "Inventory", + Description: "Inventory application", + }, + } + Dependencies = []api.Dependency{ + { + To: api.Ref{ + Name: "Gateway", + }, + From: api.Ref{ + Name: "Inventory", + }, + }, + { + To: api.Ref{ + Name: "Inventory", + }, + From: api.Ref{ + Name: "Customers", + }, + }, + } + Samples = []TestCase{ + { + fileName: "template_application_import.csv", + ExpectedApplications: Applications, + ExpectedDependencies: Dependencies, + }, + } +) diff --git a/test/api/importCSV/template_application_import.csv b/test/api/importCSV/template_application_import.csv new file mode 100644 index 000000000..80f64fdab --- /dev/null +++ b/test/api/importCSV/template_application_import.csv @@ -0,0 +1,6 @@ +Record Type 1,Application Name,Description,Comments,Business Service,Dependency,Dependency Direction,Binary Group,Binary Artifact,Binary Version,Binary Packaging,Repository Type,Repository URL,Repository Branch,Repository Path,Tag Category 1,Tag 1,Tag Category 2,Tag 2,Tag Category 3,Tag 3,Tag Category 4,Tag 4,Tag Category 5,Tag 5,Tag Category 6,Tag 6,Tag Category 7,Tag 7,Tag Category 8,Tag 8,Tag Category 9,Tag 9,Tag Category 10,Tag 10,Tag Category 11,Tag 11,Tag Category 12,Tag 12,Tag Category 13,Tag 13,Tag Category 14,Tag 14,Tag Category 15,Tag 15,Tag Category 16,Tag 16,Tag Category 17,Tag 17,Tag Category 18,Tag 18,Tag Category 19,Tag 19,Tag Category 20,Tag 20 +1,Customers,Legacy Customers management service,,Retail,,,corp.acme.demo,customers-tomcat,0.0.1-SNAPSHOT,war,git,https://git-acme.local/customers.git,,,Operating System,RHEL 8,Database,Oracle,Language,Java,Runtime,Tomcat,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +1,Inventory,Inventory service,,Retail,,,corp.acme.demo,inventory,0.1.1-SNAPSHOT,war,git,https://git-acme.local/inventory.git,,,Operating System,RHEL 8,Database,Postgresql,Language,Java,Runtime,Quarkus,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +1,Gateway,API Gateway,,Retail,,,corp.acme.demo,gateway,0.1.1-SNAPSHOT,war,git,https://git-acme.local/gateway.git,,,Operating System,RHEL 8,,,Language,Java,Runtime,Spring Boot,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +2,Gateway,,,,Inventory,southbound +2,Gateway,,,,Customers,southbound From b4acc5b1e10b4b1a8f8161584f40309294c6c93d Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Tue, 13 Jun 2023 17:23:31 +0530 Subject: [PATCH 02/20] add FilePost to Post CSV Signed-off-by: Yash Khare --- binding/client.go | 71 ++++++++++++++++++++++++++++++++-- test/api/importCSV/api_test.go | 11 ++---- 2 files changed, 70 insertions(+), 12 deletions(-) diff --git a/binding/client.go b/binding/client.go index 45b69919c..17778650c 100644 --- a/binding/client.go +++ b/binding/client.go @@ -361,7 +361,7 @@ func (r *Client) BucketPut(source, destination string) (err error) { request.Header.Set(api.Directory, api.DirectoryExpand) err = r.putDir(part, source) } else { - err = r.putFile(part, source) + err = r.loadFile(part, source) } return } @@ -449,7 +449,70 @@ func (r *Client) FilePut(path, source string, object interface{}) (err error) { request.Header.Add( api.ContentType, writer.FormDataContentType()) - err = r.putFile(part, source) + err = r.loadFile(part, source) + return + } + reply, err := r.send(request) + if err != nil { + return + } + status := reply.StatusCode + switch status { + case http.StatusOK, + http.StatusCreated: + var body []byte + body, err = io.ReadAll(reply.Body) + if err != nil { + err = liberr.Wrap(err) + return + } + err = json.Unmarshal(body, object) + if err != nil { + err = liberr.Wrap(err) + return + } + case http.StatusConflict: + err = &Conflict{Path: path} + default: + err = liberr.New(http.StatusText(status)) + } + return +} + +// +// FilePost uploads a file. +// Returns the created File resource. +func (r *Client) FilePost(path, source string, object interface{}) (err error) { + isDir, err := r.isDir(source, true) + if err != nil { + return + } + if isDir { + err = liberr.New("Source cannot be directory.") + return + } + request := func() (request *http.Request, err error) { + buf := new(bytes.Buffer) + request = &http.Request{ + Header: http.Header{}, + Method: http.MethodPost, + Body: io.NopCloser(buf), + URL: r.join(path), + } + request.Header.Set(api.Accept, binding.MIMEJSON) + writer := multipart.NewWriter(buf) + defer func() { + _ = writer.Close() + }() + part, nErr := writer.CreateFormFile(api.FileField, pathlib.Base(source)) + if err != nil { + err = liberr.Wrap(nErr) + return + } + request.Header.Add( + api.ContentType, + writer.FormDataContentType()) + err = r.loadFile(part, source) return } reply, err := r.send(request) @@ -610,8 +673,8 @@ func (r *Client) getFile(body io.Reader, path, output string) (err error) { } // -// putFile uploads plain file. -func (r *Client) putFile(writer io.Writer, input string) (err error) { +// loadFile uploads a file. +func (r *Client) loadFile(writer io.Writer, input string) (err error) { file, err := os.Open(input) if err != nil { err = liberr.Wrap(err) diff --git a/test/api/importCSV/api_test.go b/test/api/importCSV/api_test.go index 68707f379..407719838 100644 --- a/test/api/importCSV/api_test.go +++ b/test/api/importCSV/api_test.go @@ -1,20 +1,15 @@ package importCSV import ( + "bytes" "testing" - - "github.com/konveyor/tackle2-hub/api" ) func TestImportCRUD(t *testing.T) { for _, r := range Samples { t.Run("CSV_Import", func(t *testing.T) { - - // Upload CSV. - api.ImportHandler.UploadCSV() // need to work on this how to fetch files(use RichClient.Client) - - // Get. - err := Client.Get(r.fileName, r.ExpectedApplications) // Client.Get() accepts a path need to figure out the path and the object + buffer := &bytes.Buffer{} + err := Client.FilePost("/importsummaries/upload", r.fileName, buffer) if err != nil { t.Errorf(err.Error()) } From 343a266d017751d67a2ffeae9f454b0401035c26 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Wed, 14 Jun 2023 07:58:17 +0530 Subject: [PATCH 03/20] add get route Signed-off-by: Yash Khare --- binding/client.go | 4 ++-- test/api/importCSV/api_test.go | 15 ++++++++++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/binding/client.go b/binding/client.go index 17778650c..ef7d9c404 100644 --- a/binding/client.go +++ b/binding/client.go @@ -134,7 +134,7 @@ func (r *Client) Get(path string, object interface{}, params ...Param) (err erro err = liberr.Wrap(err) return } - err = json.Unmarshal(body, object) + err = json.Unmarshal(body, &object) if err != nil { err = liberr.Wrap(err) return @@ -529,7 +529,7 @@ func (r *Client) FilePost(path, source string, object interface{}) (err error) { err = liberr.Wrap(err) return } - err = json.Unmarshal(body, object) + err = json.Unmarshal(body, &object) if err != nil { err = liberr.Wrap(err) return diff --git a/test/api/importCSV/api_test.go b/test/api/importCSV/api_test.go index 407719838..003f58d7f 100644 --- a/test/api/importCSV/api_test.go +++ b/test/api/importCSV/api_test.go @@ -1,15 +1,24 @@ package importCSV import ( - "bytes" "testing" + + "github.com/konveyor/tackle2-hub/api" ) func TestImportCRUD(t *testing.T) { for _, r := range Samples { t.Run("CSV_Import", func(t *testing.T) { - buffer := &bytes.Buffer{} - err := Client.FilePost("/importsummaries/upload", r.fileName, buffer) + + // Upload CSV. + err := Client.FilePost("/importsummaries/upload", r.fileName, &r) + if err != nil { + t.Errorf(err.Error()) + } + + // Get summaries. + var destination []api.ImportSummary + err = Client.Get("/importsummaries", &destination) if err != nil { t.Errorf(err.Error()) } From a3a9f508a69e5529487e975d51afff26e98bcb70 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Wed, 14 Jun 2023 08:47:09 +0530 Subject: [PATCH 04/20] add comparison of id's Signed-off-by: Yash Khare --- test/api/importCSV/api_test.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/test/api/importCSV/api_test.go b/test/api/importCSV/api_test.go index 003f58d7f..ac2313834 100644 --- a/test/api/importCSV/api_test.go +++ b/test/api/importCSV/api_test.go @@ -11,7 +11,8 @@ func TestImportCRUD(t *testing.T) { t.Run("CSV_Import", func(t *testing.T) { // Upload CSV. - err := Client.FilePost("/importsummaries/upload", r.fileName, &r) + buffer := make(map[string]interface{}) + err := Client.FilePost("/importsummaries/upload", r.fileName, &buffer) if err != nil { t.Errorf(err.Error()) } @@ -22,6 +23,19 @@ func TestImportCRUD(t *testing.T) { if err != nil { t.Errorf(err.Error()) } + + // check if id of output is matching with buffer id + found := false + for _, d := range destination { + id := uint(buffer["id"].(float64)) + if d.ID == id { + found = true + break + } + } + if found == false { + t.Errorf("id of destination is matching with buffer id") + } }) } } From 723be079f0f296eed90147ebcc95507f4abfcacb Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Wed, 14 Jun 2023 11:54:37 +0530 Subject: [PATCH 05/20] updated variable names Signed-off-by: Yash Khare --- test/api/importCSV/api_test.go | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/test/api/importCSV/api_test.go b/test/api/importCSV/api_test.go index ac2313834..922d8bbc0 100644 --- a/test/api/importCSV/api_test.go +++ b/test/api/importCSV/api_test.go @@ -1,9 +1,8 @@ package importCSV import ( + "strconv" "testing" - - "github.com/konveyor/tackle2-hub/api" ) func TestImportCRUD(t *testing.T) { @@ -11,30 +10,19 @@ func TestImportCRUD(t *testing.T) { t.Run("CSV_Import", func(t *testing.T) { // Upload CSV. - buffer := make(map[string]interface{}) - err := Client.FilePost("/importsummaries/upload", r.fileName, &buffer) + inputData := make(map[string]interface{}) + err := Client.FilePost("/importsummaries/upload", r.fileName, &inputData) if err != nil { t.Errorf(err.Error()) } // Get summaries. - var destination []api.ImportSummary - err = Client.Get("/importsummaries", &destination) + id := uint64(inputData["id"].(float64)) + var inputID = strconv.FormatUint(id, 10) + outputImport := make(map[string]interface{}) + err = Client.Get("/importsummaries/"+inputID, &outputImport) if err != nil { - t.Errorf(err.Error()) - } - - // check if id of output is matching with buffer id - found := false - for _, d := range destination { - id := uint(buffer["id"].(float64)) - if d.ID == id { - found = true - break - } - } - if found == false { - t.Errorf("id of destination is matching with buffer id") + t.Errorf("CSV import failed") } }) } From 4049dd425dadc1af0c13299b5235e26361af9e2b Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Fri, 16 Jun 2023 17:19:56 +0530 Subject: [PATCH 06/20] added logic to compare apps and deps Signed-off-by: Yash Khare --- binding/client.go | 23 ++----- test/api/importCSV/api_test.go | 29 -------- test/api/importCSV/samples.go | 49 -------------- test/api/importcsv/api_test.go | 67 +++++++++++++++++++ test/api/{importCSV => importcsv}/pkg.go | 2 +- test/api/importcsv/samples.go | 67 +++++++++++++++++++ .../template_application_import.csv | 0 7 files changed, 141 insertions(+), 96 deletions(-) delete mode 100644 test/api/importCSV/api_test.go delete mode 100644 test/api/importCSV/samples.go create mode 100644 test/api/importcsv/api_test.go rename test/api/{importCSV => importcsv}/pkg.go (95%) create mode 100644 test/api/importcsv/samples.go rename test/api/{importCSV => importcsv}/template_application_import.csv (100%) diff --git a/binding/client.go b/binding/client.go index c951d0442..7fa246e87 100644 --- a/binding/client.go +++ b/binding/client.go @@ -8,9 +8,6 @@ import ( "encoding/json" "errors" "fmt" - "github.com/gin-gonic/gin/binding" - liberr "github.com/jortel/go-utils/error" - "github.com/konveyor/tackle2-hub/api" "io" "mime/multipart" "net" @@ -22,6 +19,10 @@ import ( "path/filepath" "strings" "time" + + "github.com/gin-gonic/gin/binding" + liberr "github.com/jortel/go-utils/error" + "github.com/konveyor/tackle2-hub/api" ) const ( @@ -349,9 +350,6 @@ func (r *Client) BucketPut(source, destination string) (err error) { request.Header.Add(api.ContentType, mp.FormDataContentType()) if isDir { request.Header.Set(api.Directory, api.DirectoryExpand) - err = r.putDir(part, source) - } else { - err = r.loadFile(part, source) } go func() { var err error @@ -371,7 +369,7 @@ func (r *Client) BucketPut(source, destination string) (err error) { if isDir { err = r.putDir(part, source) } else { - err = r.putFile(part, source) + err = r.loadFile(part, source) } }() return @@ -489,15 +487,6 @@ func (r *Client) FileSend(path, method string, fields []Field, object interface{ } } }() - part, nErr := writer.CreateFormFile(api.FileField, pathlib.Base(source)) - if err != nil { - err = liberr.Wrap(nErr) - return - } - request.Header.Add( - api.ContentType, - writer.FormDataContentType()) - err = r.loadFile(part, source) return } reply, err := r.send(request) @@ -531,7 +520,7 @@ func (r *Client) FileSend(path, method string, fields []Field, object interface{ // FilePost uploads a file. // Returns the created File resource. func (r *Client) FilePost(path, source string, object interface{}) (err error) { - isDir, err := r.isDir(source, true) + isDir, err := r.IsDir(source, true) if err != nil { return } diff --git a/test/api/importCSV/api_test.go b/test/api/importCSV/api_test.go deleted file mode 100644 index 922d8bbc0..000000000 --- a/test/api/importCSV/api_test.go +++ /dev/null @@ -1,29 +0,0 @@ -package importCSV - -import ( - "strconv" - "testing" -) - -func TestImportCRUD(t *testing.T) { - for _, r := range Samples { - t.Run("CSV_Import", func(t *testing.T) { - - // Upload CSV. - inputData := make(map[string]interface{}) - err := Client.FilePost("/importsummaries/upload", r.fileName, &inputData) - if err != nil { - t.Errorf(err.Error()) - } - - // Get summaries. - id := uint64(inputData["id"].(float64)) - var inputID = strconv.FormatUint(id, 10) - outputImport := make(map[string]interface{}) - err = Client.Get("/importsummaries/"+inputID, &outputImport) - if err != nil { - t.Errorf("CSV import failed") - } - }) - } -} diff --git a/test/api/importCSV/samples.go b/test/api/importCSV/samples.go deleted file mode 100644 index 0e79070e4..000000000 --- a/test/api/importCSV/samples.go +++ /dev/null @@ -1,49 +0,0 @@ -package importCSV - -import ( - "github.com/konveyor/tackle2-hub/api" -) - -type TestCase struct { - fileName string - ExpectedApplications []api.Application - ExpectedDependencies []api.Dependency -} - -var ( - Applications = []api.Application{ - { - Name: "Gateway", - Description: "Gateway application", - }, - { - Name: "Inventory", - Description: "Inventory application", - }, - } - Dependencies = []api.Dependency{ - { - To: api.Ref{ - Name: "Gateway", - }, - From: api.Ref{ - Name: "Inventory", - }, - }, - { - To: api.Ref{ - Name: "Inventory", - }, - From: api.Ref{ - Name: "Customers", - }, - }, - } - Samples = []TestCase{ - { - fileName: "template_application_import.csv", - ExpectedApplications: Applications, - ExpectedDependencies: Dependencies, - }, - } -) diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go new file mode 100644 index 000000000..aa1e8f6ae --- /dev/null +++ b/test/api/importcsv/api_test.go @@ -0,0 +1,67 @@ +package importcsv + +import ( + "strconv" + "testing" +) + +func TestImportCSV(t *testing.T) { + for _, r := range TestCases { + t.Run(r.fileName, func(t *testing.T) { + + // Upload CSV. + inputData := make(map[string]interface{}) + err := Client.FilePost("/importsummaries/upload", r.fileName, &inputData) + if err != nil { + t.Errorf(err.Error()) + } + + // Get summaries. + id := uint64(inputData["id"].(float64)) + var inputID = strconv.FormatUint(id, 10) + outputImport := make(map[string]interface{}) + err = Client.Get("/importsummaries/"+inputID, &outputImport) + if err != nil { + t.Errorf("CSV import failed") + } + // access the import sectio of output data to checks applications and dependencies. + imports := outputImport["Imports"] + + // fetch ExpectedApplications and ExpectedDependencies. + expectedApps := r.ExpectedApplications + expectedDeps := r.ExpectedDependencies + importList, ok := imports.([]interface{}) + if ok { + i, j := 0, 0 + for _, item := range importList { + if importMap, ok := item.(map[string]interface{}); ok { + applicationName := importMap["ApplicationName"].(string) + dependencyName := importMap["Dependency"].(string) + // if no dependency mentioned just compare the applications. + if len(dependencyName) == 0 { + if applicationName != expectedApps[i].Name { + t.Errorf("The output applications %v doesnt match with the expected applications %v", applicationName, expectedApps[i].Name) + } + i++ + } + // if dependency name present, compare the names of applications and dependencies. + if len(dependencyName) != 0 { + if applicationName != expectedApps[i].Name || dependencyName != expectedDeps[j].To.Name { + if applicationName != expectedApps[i].Name { + t.Errorf("The output applications %v doesnt match with the expected applications %v", applicationName, expectedApps[i].Name) + } + if dependencyName != expectedDeps[j].To.Name { + t.Errorf("The output dependency %v doesnt match with the expected dependency %v", dependencyName, expectedDeps[j].To.Name) + } + } + // if there is a match increment the application by 2 as there is a dependency between 2 applications and dependency only by 1. + i += 2 + j++ + } + } + } + } + + }) + } +} diff --git a/test/api/importCSV/pkg.go b/test/api/importcsv/pkg.go similarity index 95% rename from test/api/importCSV/pkg.go rename to test/api/importcsv/pkg.go index a19657c83..6ff8a1347 100644 --- a/test/api/importCSV/pkg.go +++ b/test/api/importcsv/pkg.go @@ -1,4 +1,4 @@ -package importCSV +package importcsv import ( "github.com/konveyor/tackle2-hub/binding" diff --git a/test/api/importcsv/samples.go b/test/api/importcsv/samples.go new file mode 100644 index 000000000..076cc42d4 --- /dev/null +++ b/test/api/importcsv/samples.go @@ -0,0 +1,67 @@ +package importcsv + +import ( + "github.com/konveyor/tackle2-hub/api" +) + +type TestCase struct { + fileName string + ExpectedApplications []api.Application + ExpectedDependencies []api.Dependency +} + +var ( + TestCases = []TestCase{ + { + fileName: "template_application_import.csv", + ExpectedApplications: []api.Application{ + { + Name: "Customers", + Description: "Legacy Customers management service", + }, + { + Name: "Inventory", + Description: "Inventory service", + }, + { + Name: "Gateway", + Description: "API Gateway", + }, + { + Name: "Gateway", + Description: "API Gateway", + }, + { + Name: "Inventory", + Description: "Inventory service", + }, + { + Name: "Gateway", + Description: "API Gateway", + }, + { + Name: "Customers", + Description: "Legacy Customers management service", + }, + }, + ExpectedDependencies: []api.Dependency{ + { + To: api.Ref{ + Name: "Inventory", + }, + From: api.Ref{ + Name: "Gateway", + }, + }, + { + To: api.Ref{ + Name: "Customers", + }, + From: api.Ref{ + Name: "Gateway", + }, + }, + }, + }, + } +) diff --git a/test/api/importCSV/template_application_import.csv b/test/api/importcsv/template_application_import.csv similarity index 100% rename from test/api/importCSV/template_application_import.csv rename to test/api/importcsv/template_application_import.csv From 55ae1d10df3720fd121c925eb9ee22fa2bafc2d5 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Fri, 23 Jun 2023 17:36:04 +0530 Subject: [PATCH 07/20] added Application and Dependency check Signed-off-by: Yash Khare --- binding/client.go | 86 +++++++++---------------------- test/api/importcsv/api_test.go | 92 ++++++++++++++++++++-------------- test/api/importcsv/pkg.go | 12 ++++- test/api/importcsv/samples.go | 16 ------ 4 files changed, 86 insertions(+), 120 deletions(-) diff --git a/binding/client.go b/binding/client.go index 7fa246e87..037479193 100644 --- a/binding/client.go +++ b/binding/client.go @@ -448,6 +448,29 @@ func (r *Client) FilePut(path, source string, object interface{}) (err error) { return } +// +// FilePost uploads a file. +// Returns the created File resource. +func (r *Client) FilePost(path, source string, object interface{}) (err error) { + isDir, nErr := r.IsDir(source, true) + if nErr != nil { + err = nErr + return + } + if isDir { + err = liberr.New("Must be regular file.") + return + } + fields := []Field{ + { + Name: api.FileField, + Path: source, + }, + } + err = r.FileSend(path, http.MethodPost, fields, object) + return +} + // // FileSend sends file upload from. func (r *Client) FileSend(path, method string, fields []Field, object interface{}) (err error) { @@ -516,69 +539,6 @@ func (r *Client) FileSend(path, method string, fields []Field, object interface{ return } -// -// FilePost uploads a file. -// Returns the created File resource. -func (r *Client) FilePost(path, source string, object interface{}) (err error) { - isDir, err := r.IsDir(source, true) - if err != nil { - return - } - if isDir { - err = liberr.New("Source cannot be directory.") - return - } - request := func() (request *http.Request, err error) { - buf := new(bytes.Buffer) - request = &http.Request{ - Header: http.Header{}, - Method: http.MethodPost, - Body: io.NopCloser(buf), - URL: r.join(path), - } - request.Header.Set(api.Accept, binding.MIMEJSON) - writer := multipart.NewWriter(buf) - defer func() { - _ = writer.Close() - }() - part, nErr := writer.CreateFormFile(api.FileField, pathlib.Base(source)) - if err != nil { - err = liberr.Wrap(nErr) - return - } - request.Header.Add( - api.ContentType, - writer.FormDataContentType()) - err = r.loadFile(part, source) - return - } - reply, err := r.send(request) - if err != nil { - return - } - status := reply.StatusCode - switch status { - case http.StatusOK, - http.StatusCreated: - var body []byte - body, err = io.ReadAll(reply.Body) - if err != nil { - err = liberr.Wrap(err) - return - } - err = json.Unmarshal(body, &object) - if err != nil { - err = liberr.Wrap(err) - return - } - case http.StatusConflict: - err = &Conflict{Path: path} - default: - err = liberr.New(http.StatusText(status)) - } - return -} - // // getDir downloads and expands a directory. func (r *Client) getDir(body io.Reader, output string) (err error) { diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index aa1e8f6ae..a82a21465 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -3,6 +3,8 @@ package importcsv import ( "strconv" "testing" + + "github.com/konveyor/tackle2-hub/api" ) func TestImportCSV(t *testing.T) { @@ -16,52 +18,64 @@ func TestImportCSV(t *testing.T) { t.Errorf(err.Error()) } - // Get summaries. + // Check list of Applications. + importedApps, _ := Application.List() + expectedApps := r.ExpectedApplications + for i, expectedApp := range expectedApps { + if i >= len(importedApps) { + t.Errorf("Missing imported Application: %s", expectedApp.Name) + continue + } + importedApp := importedApps[i] + if importedApp.Name != expectedApp.Name { + t.Errorf("Mismatch in imported Application: Expected %s, Actual %s", expectedApp.Name, importedApp.Name) + } + } + + // Check list of Dependencies. + importedDeps, _ := Dependency.List() + expectedDeps := r.ExpectedDependencies + for i, expectedDep := range expectedDeps { + if i >= len(importedDeps) { + t.Errorf("Missing imported Dependency: %s", expectedDep.To.Name) + continue + } + importedDep := importedDeps[i].To.Name + if importedDep != expectedDep.To.Name { + t.Errorf("Mismatch in imported Dependency: Expected %s, Actual %s", expectedDep.To.Name, importedDep) + } + } + + // fetch id's id := uint64(inputData["id"].(float64)) var inputID = strconv.FormatUint(id, 10) - outputImport := make(map[string]interface{}) - err = Client.Get("/importsummaries/"+inputID, &outputImport) + var output []api.ImportSummary + err = Client.Get("/importsummaries/", &output) if err != nil { - t.Errorf("CSV import failed") + t.Errorf("Can't get summaries of all imports") } - // access the import sectio of output data to checks applications and dependencies. - imports := outputImport["Imports"] - // fetch ExpectedApplications and ExpectedDependencies. - expectedApps := r.ExpectedApplications - expectedDeps := r.ExpectedDependencies - importList, ok := imports.([]interface{}) - if ok { - i, j := 0, 0 - for _, item := range importList { - if importMap, ok := item.(map[string]interface{}); ok { - applicationName := importMap["ApplicationName"].(string) - dependencyName := importMap["Dependency"].(string) - // if no dependency mentioned just compare the applications. - if len(dependencyName) == 0 { - if applicationName != expectedApps[i].Name { - t.Errorf("The output applications %v doesnt match with the expected applications %v", applicationName, expectedApps[i].Name) - } - i++ - } - // if dependency name present, compare the names of applications and dependencies. - if len(dependencyName) != 0 { - if applicationName != expectedApps[i].Name || dependencyName != expectedDeps[j].To.Name { - if applicationName != expectedApps[i].Name { - t.Errorf("The output applications %v doesnt match with the expected applications %v", applicationName, expectedApps[i].Name) - } - if dependencyName != expectedDeps[j].To.Name { - t.Errorf("The output dependency %v doesnt match with the expected dependency %v", dependencyName, expectedDeps[j].To.Name) - } - } - // if there is a match increment the application by 2 as there is a dependency between 2 applications and dependency only by 1. - i += 2 - j++ - } - } - } + // check for the id and return valid + // for _, imp := range output { + // if uint64(imp.ID) == id { + // if len(importedDeps)+len(importedApps) != imp.ValidCount { + // t.Errorf("Mismatch in number of valid count") + // } + // } + // } + + // Get summaries of the Input ID. + outputImport := api.ImportSummary{} + err = Client.Get("/importsummaries/"+inputID, &outputImport) + if err != nil { + t.Errorf("Could not get the CSV output") } + // Delete summaries of the Input ID. + err = Client.Delete("/importsummaries/" + inputID) + if err != nil { + t.Errorf("CSV delete failed") + } }) } } diff --git a/test/api/importcsv/pkg.go b/test/api/importcsv/pkg.go index 6ff8a1347..e10c7345c 100644 --- a/test/api/importcsv/pkg.go +++ b/test/api/importcsv/pkg.go @@ -6,8 +6,10 @@ import ( ) var ( - RichClient *binding.RichClient - Client *binding.Client + RichClient *binding.RichClient + Client *binding.Client + Application binding.Application + Dependency binding.Dependency ) func init() { @@ -16,4 +18,10 @@ func init() { // Access REST client directly Client = RichClient.Client() + + // Access Application directly + Application = RichClient.Application + + // Access Dependency directly + Dependency = RichClient.Dependency } diff --git a/test/api/importcsv/samples.go b/test/api/importcsv/samples.go index 076cc42d4..a6d4a2bc2 100644 --- a/test/api/importcsv/samples.go +++ b/test/api/importcsv/samples.go @@ -27,22 +27,6 @@ var ( Name: "Gateway", Description: "API Gateway", }, - { - Name: "Gateway", - Description: "API Gateway", - }, - { - Name: "Inventory", - Description: "Inventory service", - }, - { - Name: "Gateway", - Description: "API Gateway", - }, - { - Name: "Customers", - Description: "Legacy Customers management service", - }, }, ExpectedDependencies: []api.Dependency{ { From 606abcddde5ed27a144443c742ee0b7ad4e48a20 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Sat, 24 Jun 2023 08:30:28 +0530 Subject: [PATCH 08/20] added valid count check Signed-off-by: Yash Khare --- test/api/importcsv/api_test.go | 47 ++++++++++++++++++++++------------ test/api/importcsv/pkg.go | 2 +- test/api/importcsv/samples.go | 4 +-- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index a82a21465..19a75bb81 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -1,6 +1,7 @@ package importcsv import ( + "fmt" "strconv" "testing" @@ -9,11 +10,11 @@ import ( func TestImportCSV(t *testing.T) { for _, r := range TestCases { - t.Run(r.fileName, func(t *testing.T) { + t.Run(r.FileName, func(t *testing.T) { // Upload CSV. inputData := make(map[string]interface{}) - err := Client.FilePost("/importsummaries/upload", r.fileName, &inputData) + err := Client.FilePost("/importsummaries/upload", r.FileName, &inputData) if err != nil { t.Errorf(err.Error()) } @@ -46,23 +47,25 @@ func TestImportCSV(t *testing.T) { } } - // fetch id's + // fetch id of CSV file and convert it into required formats id := uint64(inputData["id"].(float64)) - var inputID = strconv.FormatUint(id, 10) - var output []api.ImportSummary - err = Client.Get("/importsummaries/", &output) + var inputID = strconv.FormatUint(id, 10) // to be used for API compatibility + + var outputImportSummaries []api.ImportSummary + outputMatchingSummary := api.ImportSummary{} + err = Client.Get("/importsummaries", &outputImportSummaries) if err != nil { - t.Errorf("Can't get summaries of all imports") + t.Errorf("failed to get import summary: %v", err) + } + for _, imp := range outputImportSummaries { + if uint64(imp.ID) == id { + outputMatchingSummary = imp + } + } + fmt.Println(outputMatchingSummary) + if len(importedDeps)+len(importedApps) != outputMatchingSummary.ValidCount { + t.Errorf("valid count not matching with number of applications and dependencies") } - - // check for the id and return valid - // for _, imp := range output { - // if uint64(imp.ID) == id { - // if len(importedDeps)+len(importedApps) != imp.ValidCount { - // t.Errorf("Mismatch in number of valid count") - // } - // } - // } // Get summaries of the Input ID. outputImport := api.ImportSummary{} @@ -76,6 +79,18 @@ func TestImportCSV(t *testing.T) { if err != nil { t.Errorf("CSV delete failed") } + + // Delete related Applications. + err = Application.Delete(uint(id)) + if err != nil { + t.Errorf("Application delete failed") + } + + // Delete related Dependencies. + err = Dependency.Delete(uint(id)) + if err != nil { + t.Errorf("Dependency delete failed") + } }) } } diff --git a/test/api/importcsv/pkg.go b/test/api/importcsv/pkg.go index e10c7345c..86dd7663f 100644 --- a/test/api/importcsv/pkg.go +++ b/test/api/importcsv/pkg.go @@ -17,7 +17,7 @@ func init() { RichClient = client.PrepareRichClient() // Access REST client directly - Client = RichClient.Client() + Client = RichClient.Client // Access Application directly Application = RichClient.Application diff --git a/test/api/importcsv/samples.go b/test/api/importcsv/samples.go index a6d4a2bc2..f89deaab7 100644 --- a/test/api/importcsv/samples.go +++ b/test/api/importcsv/samples.go @@ -5,7 +5,7 @@ import ( ) type TestCase struct { - fileName string + FileName string ExpectedApplications []api.Application ExpectedDependencies []api.Dependency } @@ -13,7 +13,7 @@ type TestCase struct { var ( TestCases = []TestCase{ { - fileName: "template_application_import.csv", + FileName: "template_application_import.csv", ExpectedApplications: []api.Application{ { Name: "Customers", From 69087da2a100cfa27d37bab6b093ca005c35b877 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Sat, 24 Jun 2023 08:48:00 +0530 Subject: [PATCH 09/20] passed CI Signed-off-by: Yash Khare --- test/api/importcsv/api_test.go | 8 -------- 1 file changed, 8 deletions(-) diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 19a75bb81..646e11180 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -23,10 +23,6 @@ func TestImportCSV(t *testing.T) { importedApps, _ := Application.List() expectedApps := r.ExpectedApplications for i, expectedApp := range expectedApps { - if i >= len(importedApps) { - t.Errorf("Missing imported Application: %s", expectedApp.Name) - continue - } importedApp := importedApps[i] if importedApp.Name != expectedApp.Name { t.Errorf("Mismatch in imported Application: Expected %s, Actual %s", expectedApp.Name, importedApp.Name) @@ -37,10 +33,6 @@ func TestImportCSV(t *testing.T) { importedDeps, _ := Dependency.List() expectedDeps := r.ExpectedDependencies for i, expectedDep := range expectedDeps { - if i >= len(importedDeps) { - t.Errorf("Missing imported Dependency: %s", expectedDep.To.Name) - continue - } importedDep := importedDeps[i].To.Name if importedDep != expectedDep.To.Name { t.Errorf("Mismatch in imported Dependency: Expected %s, Actual %s", expectedDep.To.Name, importedDep) From 69c4ceccd410bc23560461ef57ae095284b822fe Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Sat, 24 Jun 2023 09:47:22 +0530 Subject: [PATCH 10/20] refactor code to pass CI Signed-off-by: Yash Khare --- test/api/importcsv/api_test.go | 26 ++++++---- test/api/importcsv/samples.go | 86 ++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 10 deletions(-) diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 646e11180..5dde0ce56 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -1,7 +1,6 @@ package importcsv import ( - "fmt" "strconv" "testing" @@ -22,20 +21,28 @@ func TestImportCSV(t *testing.T) { // Check list of Applications. importedApps, _ := Application.List() expectedApps := r.ExpectedApplications - for i, expectedApp := range expectedApps { - importedApp := importedApps[i] - if importedApp.Name != expectedApp.Name { - t.Errorf("Mismatch in imported Application: Expected %s, Actual %s", expectedApp.Name, importedApp.Name) + for i, importedApp := range importedApps { + if i >= len(expectedApps) { + t.Errorf("Extra imported Application: %s", importedApp.Name) + continue + } + expectedApp := expectedApps[i].Name + if importedApp.Name != expectedApp { + t.Errorf("Mismatch in imported Application: Expected %s, Actual %s", expectedApp, importedApp.Name) } } // Check list of Dependencies. importedDeps, _ := Dependency.List() expectedDeps := r.ExpectedDependencies - for i, expectedDep := range expectedDeps { - importedDep := importedDeps[i].To.Name - if importedDep != expectedDep.To.Name { - t.Errorf("Mismatch in imported Dependency: Expected %s, Actual %s", expectedDep.To.Name, importedDep) + for i, importedDep := range importedDeps { + if i >= len(expectedDeps) { + t.Errorf("Extra imported Application: %s", importedDep.To.Name) + continue + } + expectedDep := expectedDeps[i].To.Name + if importedDep.To.Name != expectedDep { + t.Errorf("Mismatch in imported Application: Expected %s, Actual %s", expectedDep, importedDep.To.Name) } } @@ -54,7 +61,6 @@ func TestImportCSV(t *testing.T) { outputMatchingSummary = imp } } - fmt.Println(outputMatchingSummary) if len(importedDeps)+len(importedApps) != outputMatchingSummary.ValidCount { t.Errorf("valid count not matching with number of applications and dependencies") } diff --git a/test/api/importcsv/samples.go b/test/api/importcsv/samples.go index f89deaab7..56ee10628 100644 --- a/test/api/importcsv/samples.go +++ b/test/api/importcsv/samples.go @@ -18,14 +18,100 @@ var ( { Name: "Customers", Description: "Legacy Customers management service", + Bucket: &api.Ref{}, + Repository: &api.Repository{ + Kind: "git", + URL: "https://git-acme.local/customers.git", + Branch: "", + Tag: "", + Path: "", + }, + Binary: "corp.acme.demo:customers-tomcat:0.0.1-SNAPSHOT:war", + Tags: []api.TagRef{ + { + Name: "Oracle", + Source: "", + }, + { + Name: "Java", + Source: "", + }, + { + Name: "RHEL 8", + Source: "", + }, + { + Name: "Tomcat", + Source: "", + }, + }, + BusinessService: &api.Ref{ + Name: "Retail", + }, }, { Name: "Inventory", Description: "Inventory service", + Bucket: &api.Ref{}, + Repository: &api.Repository{ + Kind: "git", + URL: "https://git-acme.local/inventory.git", + Branch: "", + Tag: "", + Path: "", + }, + Binary: "corp.acme.demo:inventory:0.1.1-SNAPSHOT:war", + Tags: []api.TagRef{ + { + Name: "PostgreSQL", + Source: "", + }, + { + Name: "Java", + Source: "", + }, + { + Name: "RHEL 8", + Source: "", + }, + { + Name: "Quarkus", + Source: "", + }, + }, + BusinessService: &api.Ref{ + Name: "Retail", + }, }, { Name: "Gateway", Description: "API Gateway", + Bucket: &api.Ref{}, + Repository: &api.Repository{ + Kind: "git", + URL: "https://git-acme.local/gateway.git", + Branch: "", + Tag: "", + Path: "", + }, + Binary: "corp.acme.demo:gateway:0.1.1-SNAPSHOT:war", + Tags: []api.TagRef{ + { + Name: "Java", + Source: "", + }, + { + Name: "RHEL 8", + Source: "", + }, + { + Name: "Spring Boot", + Source: "", + }, + }, + BusinessService: &api.Ref{ + Name: "Retail", + }, }, }, ExpectedDependencies: []api.Dependency{ From 0591e584ada9b4dc04dd639f3d5616a5f9431422 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Sat, 24 Jun 2023 11:23:43 +0530 Subject: [PATCH 11/20] added all import routes Signed-off-by: Yash Khare --- test/api/importcsv/api_test.go | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 5dde0ce56..976711128 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -66,13 +66,33 @@ func TestImportCSV(t *testing.T) { } // Get summaries of the Input ID. - outputImport := api.ImportSummary{} - err = Client.Get("/importsummaries/"+inputID, &outputImport) + outputImportSummary := api.ImportSummary{} + err = Client.Get("/importsummaries/"+inputID, &outputImportSummary) if err != nil { t.Errorf("Could not get the CSV output") } - // Delete summaries of the Input ID. + // Get all imports. + var outputImports []api.Import + err = Client.Get("/imports", &outputImports) + if err != nil { + t.Errorf("Could not get the imports") + } + + // Get import of the Input Id. + outputImport := api.Import{} + err = Client.Get("/imports/"+inputID, &outputImport) + if err != nil { + t.Errorf("Import for the id failed") + } + + // Delete import of the Input Id. + err = Client.Delete("/imports/" + inputID) + if err != nil { + t.Errorf("Import delete failed") + } + + // Delete summary of the Input ID. err = Client.Delete("/importsummaries/" + inputID) if err != nil { t.Errorf("CSV delete failed") From 477c417b7dae5e8ab4c902cf48f109d60bf861ca Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Tue, 27 Jun 2023 10:50:28 +0530 Subject: [PATCH 12/20] reviewed code review to check passing CI Signed-off-by: Yash Khare --- binding/client.go | 2 +- test/api/importcsv/api_test.go | 104 +++++++++++---------------------- 2 files changed, 35 insertions(+), 71 deletions(-) diff --git a/binding/client.go b/binding/client.go index 037479193..5d05b9fda 100644 --- a/binding/client.go +++ b/binding/client.go @@ -135,7 +135,7 @@ func (r *Client) Get(path string, object interface{}, params ...Param) (err erro err = liberr.Wrap(err) return } - err = json.Unmarshal(body, &object) + err = json.Unmarshal(body, object) if err != nil { err = liberr.Wrap(err) return diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 976711128..68914da6f 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/konveyor/tackle2-hub/api" + "github.com/konveyor/tackle2-hub/test/assert" ) func TestImportCSV(t *testing.T) { @@ -12,103 +13,66 @@ func TestImportCSV(t *testing.T) { t.Run(r.FileName, func(t *testing.T) { // Upload CSV. - inputData := make(map[string]interface{}) - err := Client.FilePost("/importsummaries/upload", r.FileName, &inputData) - if err != nil { - t.Errorf(err.Error()) - } + inputData := api.ImportSummary{} + assert.Must(t, Client.FilePost(api.SummariesRoot+"/upload", r.FileName, &inputData)) // Check list of Applications. - importedApps, _ := Application.List() + gotApps, _ := Application.List() expectedApps := r.ExpectedApplications - for i, importedApp := range importedApps { - if i >= len(expectedApps) { - t.Errorf("Extra imported Application: %s", importedApp.Name) - continue - } - expectedApp := expectedApps[i].Name - if importedApp.Name != expectedApp { - t.Errorf("Mismatch in imported Application: Expected %s, Actual %s", expectedApp, importedApp.Name) + if len(gotApps) != len(expectedApps) { + t.Errorf("Mismatch in number of imported Applications: Expected %d, Actual %d", len(expectedApps), len(gotApps)) + } else { + for i, importedApp := range gotApps { + assert.FlatEqual(expectedApps[i].Name, importedApp.Name) + assert.FlatEqual(expectedApps[i].Description, importedApp.Description) + assert.FlatEqual(expectedApps[i].Repository.Kind, importedApp.Repository.Kind) + assert.FlatEqual(expectedApps[i].Repository.URL, importedApp.Repository.URL) + assert.FlatEqual(expectedApps[i].Binary, importedApp.Binary) + for j, tag := range expectedApps[i].Tags { + assert.FlatEqual(tag.Name, importedApp.Tags[j].Name) + } + assert.FlatEqual(expectedApps[i].BusinessService.Name, importedApp.BusinessService.Name) } } // Check list of Dependencies. - importedDeps, _ := Dependency.List() + gotDeps, _ := Dependency.List() expectedDeps := r.ExpectedDependencies - for i, importedDep := range importedDeps { - if i >= len(expectedDeps) { - t.Errorf("Extra imported Application: %s", importedDep.To.Name) - continue - } - expectedDep := expectedDeps[i].To.Name - if importedDep.To.Name != expectedDep { - t.Errorf("Mismatch in imported Application: Expected %s, Actual %s", expectedDep, importedDep.To.Name) + if len(gotDeps) != len(expectedDeps) { + t.Errorf("Mismatch in number of imported Dependencies: Expected %d, Actual %d", len(expectedDeps), len(gotDeps)) + } else { + for i, importedDep := range gotDeps { + expectedDep := expectedDeps[i].To.Name + if importedDep.To.Name != expectedDep { + t.Errorf("Mismatch in imported Dependency: Expected %s, Actual %s", expectedDep, importedDep.To.Name) + } } } // fetch id of CSV file and convert it into required formats - id := uint64(inputData["id"].(float64)) - var inputID = strconv.FormatUint(id, 10) // to be used for API compatibility + var inputID = strconv.FormatUint(uint64(inputData.ID), 10) // to be used for API compatibility var outputImportSummaries []api.ImportSummary outputMatchingSummary := api.ImportSummary{} - err = Client.Get("/importsummaries", &outputImportSummaries) - if err != nil { - t.Errorf("failed to get import summary: %v", err) - } + assert.Should(t, Client.Get(api.SummariesRoot, &outputImportSummaries)) for _, imp := range outputImportSummaries { - if uint64(imp.ID) == id { + if uint(imp.ID) == inputData.ID { outputMatchingSummary = imp } } - if len(importedDeps)+len(importedApps) != outputMatchingSummary.ValidCount { - t.Errorf("valid count not matching with number of applications and dependencies") - } + assert.FlatEqual(len(expectedApps)+len(expectedDeps), outputMatchingSummary.ValidCount) // Get summaries of the Input ID. outputImportSummary := api.ImportSummary{} - err = Client.Get("/importsummaries/"+inputID, &outputImportSummary) - if err != nil { - t.Errorf("Could not get the CSV output") - } + assert.Should(t, Client.Get(api.SummariesRoot+"/"+inputID, &outputImportSummary)) // Get all imports. var outputImports []api.Import - err = Client.Get("/imports", &outputImports) - if err != nil { - t.Errorf("Could not get the imports") - } + assert.Should(t, Client.Get(api.ImportsRoot, &outputImports)) - // Get import of the Input Id. + // Get import of the specific Input Id. outputImport := api.Import{} - err = Client.Get("/imports/"+inputID, &outputImport) - if err != nil { - t.Errorf("Import for the id failed") - } - - // Delete import of the Input Id. - err = Client.Delete("/imports/" + inputID) - if err != nil { - t.Errorf("Import delete failed") - } - - // Delete summary of the Input ID. - err = Client.Delete("/importsummaries/" + inputID) - if err != nil { - t.Errorf("CSV delete failed") - } - - // Delete related Applications. - err = Application.Delete(uint(id)) - if err != nil { - t.Errorf("Application delete failed") - } - - // Delete related Dependencies. - err = Dependency.Delete(uint(id)) - if err != nil { - t.Errorf("Dependency delete failed") - } + assert.Should(t, Client.Get(api.ImportsRoot+"/"+inputID, &outputImport)) }) } } From b1fdbc5a94046d5b72ff696b5f393d128b5a0a2b Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Wed, 28 Jun 2023 16:32:53 +0530 Subject: [PATCH 13/20] added application and dependency check with review Signed-off-by: Yash Khare --- binding/client.go | 9 ++-- migration/v2/model/dependency.go | 4 +- test/api/importcsv/api_test.go | 73 ++++++++++++++++++++++++++------ 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/binding/client.go b/binding/client.go index 5d05b9fda..dfe48e4bd 100644 --- a/binding/client.go +++ b/binding/client.go @@ -193,7 +193,6 @@ func (r *Client) Post(path string, object interface{}) (err error) { default: err = liberr.New(http.StatusText(status)) } - return } @@ -369,7 +368,7 @@ func (r *Client) BucketPut(source, destination string) (err error) { if isDir { err = r.putDir(part, source) } else { - err = r.loadFile(part, source) + err = r.putFile(part, source) } }() return @@ -449,7 +448,7 @@ func (r *Client) FilePut(path, source string, object interface{}) (err error) { } // -// FilePost uploads a file. +// FilePut uploads a file. // Returns the created File resource. func (r *Client) FilePost(path, source string, object interface{}) (err error) { isDir, nErr := r.IsDir(source, true) @@ -670,8 +669,8 @@ func (r *Client) getFile(body io.Reader, path, output string) (err error) { } // -// loadFile uploads a file. -func (r *Client) loadFile(writer io.Writer, input string) (err error) { +// putFile uploads plain file. +func (r *Client) putFile(writer io.Writer, input string) (err error) { file, err := os.Open(input) if err != nil { err = liberr.Wrap(err) diff --git a/migration/v2/model/dependency.go b/migration/v2/model/dependency.go index 6aa1974c9..3aa459357 100644 --- a/migration/v2/model/dependency.go +++ b/migration/v2/model/dependency.go @@ -11,9 +11,9 @@ var depMutex sync.Mutex type Dependency struct { Model - ToID uint `gorm:"index"` + ToID uint `gorm:"uniqueIndex:dependency_primary_key"` To *Application `gorm:"foreignKey:ToID;constraint:OnDelete:CASCADE"` - FromID uint `gorm:"index"` + FromID uint `gorm:"uniqueIndex:dependency_primary_key"` From *Application `gorm:"foreignKey:FromID;constraint:OnDelete:CASCADE"` } diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 68914da6f..9b682e3e0 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -3,8 +3,10 @@ package importcsv import ( "strconv" "testing" + "time" "github.com/konveyor/tackle2-hub/api" + "github.com/konveyor/tackle2-hub/binding" "github.com/konveyor/tackle2-hub/test/assert" ) @@ -14,7 +16,10 @@ func TestImportCSV(t *testing.T) { // Upload CSV. inputData := api.ImportSummary{} - assert.Must(t, Client.FilePost(api.SummariesRoot+"/upload", r.FileName, &inputData)) + assert.Must(t, Client.FilePost(api.UploadRoot, r.FileName, &inputData)) + + // Since uploading the CSV happens asynchronously we need to wait for the upload to check Applications and Dependencies. + time.Sleep(time.Second * 3) // Check list of Applications. gotApps, _ := Application.List() @@ -23,15 +28,29 @@ func TestImportCSV(t *testing.T) { t.Errorf("Mismatch in number of imported Applications: Expected %d, Actual %d", len(expectedApps), len(gotApps)) } else { for i, importedApp := range gotApps { - assert.FlatEqual(expectedApps[i].Name, importedApp.Name) - assert.FlatEqual(expectedApps[i].Description, importedApp.Description) - assert.FlatEqual(expectedApps[i].Repository.Kind, importedApp.Repository.Kind) - assert.FlatEqual(expectedApps[i].Repository.URL, importedApp.Repository.URL) - assert.FlatEqual(expectedApps[i].Binary, importedApp.Binary) + if expectedApps[i].Name != importedApp.Name { + t.Errorf("Mismatch in name of imported Application: Expected %s, Actual %s", expectedApps[i].Name, importedApp.Name) + } + if expectedApps[i].Description != importedApp.Description { + t.Errorf("Mismatch in description of imported Application: Expected %s, Actual %s", expectedApps[i].Description, importedApp.Description) + } + if expectedApps[i].Repository.Kind != importedApp.Repository.Kind { + t.Errorf("Mismatch in repository's kind ofimported Application: Expected %s, Actual %s", expectedApps[i].Repository.Kind, importedApp.Repository.Kind) + } + if expectedApps[i].Repository.URL != importedApp.Repository.URL { + t.Errorf("Mismatch in repository's url of imported Application: Expected %s, Actual %s", expectedApps[i].Repository.URL, importedApp.Repository.URL) + } + if expectedApps[i].Binary != importedApp.Binary { + t.Errorf("Mismatch in binary of imported Application: Expected %s, Actual %s", expectedApps[i].Binary, importedApp.Binary) + } for j, tag := range expectedApps[i].Tags { - assert.FlatEqual(tag.Name, importedApp.Tags[j].Name) + if tag.Name != importedApp.Tags[j].Name { + t.Errorf("Mismatch in tag name of imported Application: Expected %s, Actual %s", tag.Name, importedApp.Tags[j].Name) + } + } + if expectedApps[i].BusinessService.Name != importedApp.BusinessService.Name { + t.Errorf("Mismatch in name of the BusinessService of imported Application: Expected %s, Actual %s", expectedApps[i].BusinessService.Name, importedApp.BusinessService.Name) } - assert.FlatEqual(expectedApps[i].BusinessService.Name, importedApp.BusinessService.Name) } } @@ -62,17 +81,45 @@ func TestImportCSV(t *testing.T) { } assert.FlatEqual(len(expectedApps)+len(expectedDeps), outputMatchingSummary.ValidCount) + // inject import summary id into Summary root + path := binding.Path(api.SummaryRoot).Inject(binding.Params{api.ID: inputID}) + // Get summaries of the Input ID. outputImportSummary := api.ImportSummary{} - assert.Should(t, Client.Get(api.SummariesRoot+"/"+inputID, &outputImportSummary)) + assert.Should(t, Client.Get(path, &outputImportSummary)) + + // Delete import summary + // assert.Should(t, Client.Delete(path)) // Get all imports. var outputImports []api.Import assert.Should(t, Client.Get(api.ImportsRoot, &outputImports)) - - // Get import of the specific Input Id. - outputImport := api.Import{} - assert.Should(t, Client.Get(api.ImportsRoot+"/"+inputID, &outputImport)) + j, k := 0, 0 + for _, imp := range outputImports { + if imp["recordType1"] == 1 && j < len(expectedApps) { + // An Application with no dependencies. + if expectedApps[j].Name != imp["applicationName"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedApps[j].Name, imp["applicationName"]) + } + if expectedApps[j].Description != imp["description"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedApps[j].Description, imp["description"]) + } + if expectedApps[j].BusinessService.Name != imp["businessService"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedApps[j].BusinessService.Name, imp["businessService"]) + } + j++ + } + if imp["recordType1"] == 2 && k < len(expectedDeps) { + // An Application with Dependencies. + if expectedDeps[k].From.Name != imp["applicationName"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedDeps[k].From.Name, imp["applicationName"]) + } + if expectedDeps[k].To.Name != imp["dependency"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedDeps[k].To.Name, imp["dependency"]) + } + k++ + } + } }) } } From 2f3835bd549f97f252ca77751e3b6adb99844cd4 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Thu, 29 Jun 2023 18:50:55 +0530 Subject: [PATCH 14/20] added download root Signed-off-by: Yash Khare --- binding/client.go | 2 +- migration/v2/model/dependency.go | 4 +-- test/api/importcsv/api_test.go | 43 ++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/binding/client.go b/binding/client.go index dfe48e4bd..b022644c1 100644 --- a/binding/client.go +++ b/binding/client.go @@ -448,7 +448,7 @@ func (r *Client) FilePut(path, source string, object interface{}) (err error) { } // -// FilePut uploads a file. +// FilePost uploads a file. // Returns the created File resource. func (r *Client) FilePost(path, source string, object interface{}) (err error) { isDir, nErr := r.IsDir(source, true) diff --git a/migration/v2/model/dependency.go b/migration/v2/model/dependency.go index 3aa459357..6aa1974c9 100644 --- a/migration/v2/model/dependency.go +++ b/migration/v2/model/dependency.go @@ -11,9 +11,9 @@ var depMutex sync.Mutex type Dependency struct { Model - ToID uint `gorm:"uniqueIndex:dependency_primary_key"` + ToID uint `gorm:"index"` To *Application `gorm:"foreignKey:ToID;constraint:OnDelete:CASCADE"` - FromID uint `gorm:"uniqueIndex:dependency_primary_key"` + FromID uint `gorm:"index"` From *Application `gorm:"foreignKey:FromID;constraint:OnDelete:CASCADE"` } diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 9b682e3e0..024126982 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -1,6 +1,7 @@ package importcsv import ( + "os" "strconv" "testing" "time" @@ -82,14 +83,11 @@ func TestImportCSV(t *testing.T) { assert.FlatEqual(len(expectedApps)+len(expectedDeps), outputMatchingSummary.ValidCount) // inject import summary id into Summary root - path := binding.Path(api.SummaryRoot).Inject(binding.Params{api.ID: inputID}) + pathForImportSummary := binding.Path(api.SummaryRoot).Inject(binding.Params{api.ID: inputID}) // Get summaries of the Input ID. outputImportSummary := api.ImportSummary{} - assert.Should(t, Client.Get(path, &outputImportSummary)) - - // Delete import summary - // assert.Should(t, Client.Delete(path)) + assert.Should(t, Client.Get(pathForImportSummary, &outputImportSummary)) // Get all imports. var outputImports []api.Import @@ -120,6 +118,41 @@ func TestImportCSV(t *testing.T) { k++ } } + + // Download the csv. + err := Client.FileGet(api.DownloadRoot, "downloadcsv.csv") + if err != nil { + t.Errorf(err.Error()) + } + + // Compare contents of the csv. + file1, err := os.Open("downloadcsv.csv") + if err != nil { + t.Errorf(err.Error()) + return + } + defer file1.Close() + + // Open the second CSV file + file2, err := os.Open("template_application_import.csv") + if err != nil { + t.Errorf(err.Error()) + return + } + defer file2.Close() + + // TODO: Compare both the files + + // Delete import summary + assert.Should(t, Client.Delete(pathForImportSummary)) + + // Delete all imports + id := 1 + for id <= len(expectedApps)+len(expectedDeps) { + pathForImport := binding.Path(api.ImportRoot).Inject(binding.Params{api.ID: id}) + assert.Should(t, Client.Delete(pathForImport)) + id++ + } }) } } From 619f697aed9371a164d8eeb56b6a3e755f9f0875 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Thu, 29 Jun 2023 19:45:11 +0530 Subject: [PATCH 15/20] added comparison functionality for both csv files Signed-off-by: Yash Khare --- test/api/importcsv/api_test.go | 65 +++++++++++++++++++++++++++++++--- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 024126982..1f73706ef 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -1,6 +1,7 @@ package importcsv import ( + "encoding/csv" "os" "strconv" "testing" @@ -120,13 +121,14 @@ func TestImportCSV(t *testing.T) { } // Download the csv. - err := Client.FileGet(api.DownloadRoot, "downloadcsv.csv") + pathToOutputCSV := "downloadcsv.csv" + err := Client.FileGet(api.DownloadRoot, pathToOutputCSV) if err != nil { t.Errorf(err.Error()) } // Compare contents of the csv. - file1, err := os.Open("downloadcsv.csv") + file1, err := os.Open(pathToOutputCSV) if err != nil { t.Errorf(err.Error()) return @@ -134,14 +136,69 @@ func TestImportCSV(t *testing.T) { defer file1.Close() // Open the second CSV file - file2, err := os.Open("template_application_import.csv") + file2, err := os.Open(r.FileName) if err != nil { t.Errorf(err.Error()) return } defer file2.Close() - // TODO: Compare both the files + // Read both the CSV files for comparison. + reader1 := csv.NewReader(file1) + reader2 := csv.NewReader(file2) + + column1, err := reader1.Read() + if err != nil { + t.Errorf(err.Error()) + } + + columm2, err := reader2.Read() + if err != nil { + t.Errorf(err.Error()) + } + + // Check number of columns. + if len(column1) != len(columm2) { + t.Errorf("The Content of both the CSV files are different") + } + + // Check column names. + for i := range column1 { + if column1[i] != columm2[i] { + t.Errorf("Mismatch in the Column Names") + } + } + + // Compare rest of the contents of the files. + reader1.FieldsPerRecord = -1 + item1, err := reader1.ReadAll() + if err != nil { + t.Errorf(err.Error()) + } + + reader2.FieldsPerRecord = -1 + item2, err := reader2.ReadAll() + if err != nil { + t.Errorf(err.Error()) + } + + // Compare number of records present + if len(item1) != len(item2) { + t.Errorf("Mismatch in number of records present") + } + + // Compare each value. + for i := 0; i < len(item1); i++ { + if len(item1[i]) != len(item2[i]) { + t.Errorf("Mismatch in number of values") + } + + for j := 0; j < len(item1[i]); j++ { + if item1[i][j] != item2[i][j] { + t.Errorf("Mismatch in values") + } + } + } // Delete import summary assert.Should(t, Client.Delete(pathForImportSummary)) From af3d42c441db35aac8a0c31182ca0325acfde49b Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Thu, 29 Jun 2023 19:56:36 +0530 Subject: [PATCH 16/20] remove created file after comparison Signed-off-by: Yash Khare --- test/api/importcsv/api_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 1f73706ef..b4d9aab04 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -182,7 +182,7 @@ func TestImportCSV(t *testing.T) { t.Errorf(err.Error()) } - // Compare number of records present + // Compare number of records present. if len(item1) != len(item2) { t.Errorf("Mismatch in number of records present") } @@ -200,6 +200,12 @@ func TestImportCSV(t *testing.T) { } } + // Remove the CSV file created. + err = os.Remove(pathToOutputCSV) + if err != nil { + t.Errorf(err.Error()) + } + // Delete import summary assert.Should(t, Client.Delete(pathForImportSummary)) From adffc15d9f65cdfa131e98ef93abed26ecb5ee48 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Fri, 30 Jun 2023 08:42:59 +0530 Subject: [PATCH 17/20] refactor comparison and add to test-api-matrix Signed-off-by: Yash Khare --- binding/client.go | 9 ++-- docs/test-api-matrix.md | 2 +- test/api/importcsv/api_test.go | 85 ++++++---------------------------- 3 files changed, 20 insertions(+), 76 deletions(-) diff --git a/binding/client.go b/binding/client.go index b022644c1..6b51dcb48 100644 --- a/binding/client.go +++ b/binding/client.go @@ -8,6 +8,9 @@ import ( "encoding/json" "errors" "fmt" + "github.com/gin-gonic/gin/binding" + liberr "github.com/jortel/go-utils/error" + "github.com/konveyor/tackle2-hub/api" "io" "mime/multipart" "net" @@ -18,11 +21,7 @@ import ( pathlib "path" "path/filepath" "strings" - "time" - - "github.com/gin-gonic/gin/binding" - liberr "github.com/jortel/go-utils/error" - "github.com/konveyor/tackle2-hub/api" + "time" ) const ( diff --git a/docs/test-api-matrix.md b/docs/test-api-matrix.md index 1fc827eb4..16961d1d0 100644 --- a/docs/test-api-matrix.md +++ b/docs/test-api-matrix.md @@ -7,7 +7,7 @@ application|:white_check_mark: partially|:heavy_check_mark:|| bucket||||partially within application dependency|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:| file|:heavy_check_mark:|:heavy_check_mark:|| -import|||| +import|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:| review|||| **Controls**|||| businessservice|:heavy_check_mark:|:heavy_check_mark:|| diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index b4d9aab04..f030525f0 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -1,7 +1,7 @@ package importcsv import ( - "encoding/csv" + "io/ioutil" "os" "strconv" "testing" @@ -121,87 +121,32 @@ func TestImportCSV(t *testing.T) { } // Download the csv. - pathToOutputCSV := "downloadcsv.csv" - err := Client.FileGet(api.DownloadRoot, pathToOutputCSV) + pathToGotCSV := "downloadcsv.csv" + err := Client.FileGet(api.DownloadRoot, pathToGotCSV) if err != nil { - t.Errorf(err.Error()) - } - - // Compare contents of the csv. - file1, err := os.Open(pathToOutputCSV) - if err != nil { - t.Errorf(err.Error()) - return - } - defer file1.Close() - - // Open the second CSV file - file2, err := os.Open(r.FileName) - if err != nil { - t.Errorf(err.Error()) - return + t.Errorf("Error downloading CSV: %v", err) } - defer file2.Close() - - // Read both the CSV files for comparison. - reader1 := csv.NewReader(file1) - reader2 := csv.NewReader(file2) - column1, err := reader1.Read() + // Read the got CSV file. + gotCSV, err := ioutil.ReadFile(pathToGotCSV) if err != nil { - t.Errorf(err.Error()) + t.Errorf("Error reading CSV: %s", pathToGotCSV) } + gotCSVString := string(gotCSV) - columm2, err := reader2.Read() + // Read the expected CSV file. + expectedCSV, err := ioutil.ReadFile(r.FileName) if err != nil { - t.Errorf(err.Error()) + t.Errorf("Error reading CSV: %s", r.FileName) } + expectedCSVString := string(expectedCSV) - // Check number of columns. - if len(column1) != len(columm2) { - t.Errorf("The Content of both the CSV files are different") - } - - // Check column names. - for i := range column1 { - if column1[i] != columm2[i] { - t.Errorf("Mismatch in the Column Names") - } - } - - // Compare rest of the contents of the files. - reader1.FieldsPerRecord = -1 - item1, err := reader1.ReadAll() - if err != nil { - t.Errorf(err.Error()) - } - - reader2.FieldsPerRecord = -1 - item2, err := reader2.ReadAll() - if err != nil { - t.Errorf(err.Error()) - } - - // Compare number of records present. - if len(item1) != len(item2) { - t.Errorf("Mismatch in number of records present") - } - - // Compare each value. - for i := 0; i < len(item1); i++ { - if len(item1[i]) != len(item2[i]) { - t.Errorf("Mismatch in number of values") - } - - for j := 0; j < len(item1[i]); j++ { - if item1[i][j] != item2[i][j] { - t.Errorf("Mismatch in values") - } - } + if gotCSVString != expectedCSVString { + t.Errorf("The CSV files have different content %s and %s", gotCSVString, expectedCSVString) } // Remove the CSV file created. - err = os.Remove(pathToOutputCSV) + err = os.Remove(pathToGotCSV) if err != nil { t.Errorf(err.Error()) } From 97620642c9589adeae17bacc6a1d16dfe15c1c12 Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Sat, 1 Jul 2023 12:04:28 +0530 Subject: [PATCH 18/20] added equality checks to the code Signed-off-by: Yash Khare --- docs/test-api-matrix.md | 2 +- test/api/importcsv/api_test.go | 123 ++++++++++++++++++--------------- 2 files changed, 68 insertions(+), 57 deletions(-) diff --git a/docs/test-api-matrix.md b/docs/test-api-matrix.md index 16961d1d0..193551962 100644 --- a/docs/test-api-matrix.md +++ b/docs/test-api-matrix.md @@ -7,7 +7,7 @@ application|:white_check_mark: partially|:heavy_check_mark:|| bucket||||partially within application dependency|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:| file|:heavy_check_mark:|:heavy_check_mark:|| -import|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:| +import||:heavy_check_mark:|:heavy_check_mark:| review|||| **Controls**|||| businessservice|:heavy_check_mark:|:heavy_check_mark:|| diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index f030525f0..0c3d5490e 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -3,10 +3,8 @@ package importcsv import ( "io/ioutil" "os" - "strconv" "testing" "time" - "github.com/konveyor/tackle2-hub/api" "github.com/konveyor/tackle2-hub/binding" "github.com/konveyor/tackle2-hub/test/assert" @@ -20,59 +18,66 @@ func TestImportCSV(t *testing.T) { inputData := api.ImportSummary{} assert.Must(t, Client.FilePost(api.UploadRoot, r.FileName, &inputData)) + // inject import summary id into Summary root + pathForImportSummary := binding.Path(api.SummaryRoot).Inject(binding.Params{api.ID: inputData.ID}) + // Since uploading the CSV happens asynchronously we need to wait for the upload to check Applications and Dependencies. - time.Sleep(time.Second * 3) + time.Sleep(time.Second) + + // Code below not working as expected need to check + + // checkImport := api.ImportSummary{} + // for checkImport.ValidCount + checkImport.InvalidCount != len(r.ExpectedApplications)+len(r.ExpectedDependencies){ + // assert.Should(t, Client.Get(pathForImportSummary, &checkImport)) + // } // Check list of Applications. gotApps, _ := Application.List() - expectedApps := r.ExpectedApplications - if len(gotApps) != len(expectedApps) { - t.Errorf("Mismatch in number of imported Applications: Expected %d, Actual %d", len(expectedApps), len(gotApps)) + if len(gotApps) != len(r.ExpectedApplications) { + t.Errorf("Mismatch in number of imported Applications: Expected %d, Actual %d", len(r.ExpectedApplications), len(gotApps)) } else { for i, importedApp := range gotApps { - if expectedApps[i].Name != importedApp.Name { - t.Errorf("Mismatch in name of imported Application: Expected %s, Actual %s", expectedApps[i].Name, importedApp.Name) + if r.ExpectedApplications[i].Name != importedApp.Name { + t.Errorf("Mismatch in name of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Name, importedApp.Name) } - if expectedApps[i].Description != importedApp.Description { - t.Errorf("Mismatch in description of imported Application: Expected %s, Actual %s", expectedApps[i].Description, importedApp.Description) + if r.ExpectedApplications[i].Description != importedApp.Description { + t.Errorf("Mismatch in description of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Description, importedApp.Description) } - if expectedApps[i].Repository.Kind != importedApp.Repository.Kind { - t.Errorf("Mismatch in repository's kind ofimported Application: Expected %s, Actual %s", expectedApps[i].Repository.Kind, importedApp.Repository.Kind) + if r.ExpectedApplications[i].Repository.Kind != importedApp.Repository.Kind { + t.Errorf("Mismatch in repository's kind ofimported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Repository.Kind, importedApp.Repository.Kind) } - if expectedApps[i].Repository.URL != importedApp.Repository.URL { - t.Errorf("Mismatch in repository's url of imported Application: Expected %s, Actual %s", expectedApps[i].Repository.URL, importedApp.Repository.URL) + if r.ExpectedApplications[i].Repository.URL != importedApp.Repository.URL { + t.Errorf("Mismatch in repository's url of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Repository.URL, importedApp.Repository.URL) } - if expectedApps[i].Binary != importedApp.Binary { - t.Errorf("Mismatch in binary of imported Application: Expected %s, Actual %s", expectedApps[i].Binary, importedApp.Binary) + if r.ExpectedApplications[i].Binary != importedApp.Binary { + t.Errorf("Mismatch in binary of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Binary, importedApp.Binary) } - for j, tag := range expectedApps[i].Tags { + for j, tag := range r.ExpectedApplications[i].Tags { if tag.Name != importedApp.Tags[j].Name { t.Errorf("Mismatch in tag name of imported Application: Expected %s, Actual %s", tag.Name, importedApp.Tags[j].Name) } } - if expectedApps[i].BusinessService.Name != importedApp.BusinessService.Name { - t.Errorf("Mismatch in name of the BusinessService of imported Application: Expected %s, Actual %s", expectedApps[i].BusinessService.Name, importedApp.BusinessService.Name) + if r.ExpectedApplications[i].BusinessService.Name != importedApp.BusinessService.Name { + t.Errorf("Mismatch in name of the BusinessService of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].BusinessService.Name, importedApp.BusinessService.Name) } } } // Check list of Dependencies. gotDeps, _ := Dependency.List() - expectedDeps := r.ExpectedDependencies - if len(gotDeps) != len(expectedDeps) { - t.Errorf("Mismatch in number of imported Dependencies: Expected %d, Actual %d", len(expectedDeps), len(gotDeps)) + if len(gotDeps) != len(r.ExpectedDependencies) { + t.Errorf("Mismatch in number of imported Dependencies: Expected %d, Actual %d", len(r.ExpectedDependencies), len(gotDeps)) } else { for i, importedDep := range gotDeps { - expectedDep := expectedDeps[i].To.Name - if importedDep.To.Name != expectedDep { - t.Errorf("Mismatch in imported Dependency: Expected %s, Actual %s", expectedDep, importedDep.To.Name) + if importedDep.To.Name != r.ExpectedDependencies[i].To.Name { + t.Errorf("Mismatch in imported Dependency: Expected %s, Actual %s", r.ExpectedDependencies[i].To.Name, importedDep.To.Name) + } + if importedDep.From.Name != r.ExpectedDependencies[i].From.Name { + t.Errorf("Mismatch in imported Dependency: Expected %s, Actual %s", r.ExpectedDependencies[i].From.Name, importedDep.From.Name) } } } - // fetch id of CSV file and convert it into required formats - var inputID = strconv.FormatUint(uint64(inputData.ID), 10) // to be used for API compatibility - var outputImportSummaries []api.ImportSummary outputMatchingSummary := api.ImportSummary{} assert.Should(t, Client.Get(api.SummariesRoot, &outputImportSummaries)) @@ -81,10 +86,11 @@ func TestImportCSV(t *testing.T) { outputMatchingSummary = imp } } - assert.FlatEqual(len(expectedApps)+len(expectedDeps), outputMatchingSummary.ValidCount) - // inject import summary id into Summary root - pathForImportSummary := binding.Path(api.SummaryRoot).Inject(binding.Params{api.ID: inputID}) + // Compare the number of imports. + if len(r.ExpectedApplications)+len(r.ExpectedDependencies) != outputMatchingSummary.ValidCount { + t.Errorf("Mismatch in no. of imports: expected %v, got %v", len(r.ExpectedApplications)+len(r.ExpectedDependencies), outputMatchingSummary.ValidCount) + } // Get summaries of the Input ID. outputImportSummary := api.ImportSummary{} @@ -93,28 +99,35 @@ func TestImportCSV(t *testing.T) { // Get all imports. var outputImports []api.Import assert.Should(t, Client.Get(api.ImportsRoot, &outputImports)) + + // Check for number of imports. + if len(outputImports) != len(r.ExpectedApplications)+len(r.ExpectedDependencies) { + t.Errorf("Mismatch in number of imports") + } + + // Checks for individual applications and dependencies. j, k := 0, 0 for _, imp := range outputImports { - if imp["recordType1"] == 1 && j < len(expectedApps) { + if imp["recordType1"] == 1 && j < len(r.ExpectedApplications) { // An Application with no dependencies. - if expectedApps[j].Name != imp["applicationName"] { - t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedApps[j].Name, imp["applicationName"]) + if r.ExpectedApplications[j].Name != imp["applicationName"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", r.ExpectedApplications[j].Name, imp["applicationName"]) } - if expectedApps[j].Description != imp["description"] { - t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedApps[j].Description, imp["description"]) + if r.ExpectedApplications[j].Description != imp["description"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", r.ExpectedApplications[j].Description, imp["description"]) } - if expectedApps[j].BusinessService.Name != imp["businessService"] { - t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedApps[j].BusinessService.Name, imp["businessService"]) + if r.ExpectedApplications[j].BusinessService.Name != imp["businessService"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", r.ExpectedApplications[j].BusinessService.Name, imp["businessService"]) } j++ } - if imp["recordType1"] == 2 && k < len(expectedDeps) { + if imp["recordType1"] == 2 && k < len(r.ExpectedDependencies) { // An Application with Dependencies. - if expectedDeps[k].From.Name != imp["applicationName"] { - t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedDeps[k].From.Name, imp["applicationName"]) + if r.ExpectedDependencies[k].From.Name != imp["applicationName"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", r.ExpectedDependencies[k].From.Name, imp["applicationName"]) } - if expectedDeps[k].To.Name != imp["dependency"] { - t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedDeps[k].To.Name, imp["dependency"]) + if r.ExpectedDependencies[k].To.Name != imp["dependency"] { + t.Errorf("Mismatch in name of import: Expected %s, Actual %s", r.ExpectedDependencies[k].To.Name, imp["dependency"]) } k++ } @@ -122,10 +135,7 @@ func TestImportCSV(t *testing.T) { // Download the csv. pathToGotCSV := "downloadcsv.csv" - err := Client.FileGet(api.DownloadRoot, pathToGotCSV) - if err != nil { - t.Errorf("Error downloading CSV: %v", err) - } + assert.Should(t, Client.FileGet(api.DownloadRoot, pathToGotCSV)) // Read the got CSV file. gotCSV, err := ioutil.ReadFile(pathToGotCSV) @@ -140,7 +150,6 @@ func TestImportCSV(t *testing.T) { t.Errorf("Error reading CSV: %s", r.FileName) } expectedCSVString := string(expectedCSV) - if gotCSVString != expectedCSVString { t.Errorf("The CSV files have different content %s and %s", gotCSVString, expectedCSVString) } @@ -151,15 +160,17 @@ func TestImportCSV(t *testing.T) { t.Errorf(err.Error()) } - // Delete import summary - assert.Should(t, Client.Delete(pathForImportSummary)) + // Delete imported summaries + assert.Must(t, Client.Delete(pathForImportSummary)) + + // Delete imported Applications. + for _, apps := range gotApps { + assert.Must(t, Application.Delete(apps.ID)) + } - // Delete all imports - id := 1 - for id <= len(expectedApps)+len(expectedDeps) { - pathForImport := binding.Path(api.ImportRoot).Inject(binding.Params{api.ID: id}) - assert.Should(t, Client.Delete(pathForImport)) - id++ + // Delete imported Dependencies. + for _, deps := range gotDeps { + assert.Must(t, Dependency.Delete(deps.ID)) } }) } From ee0db775e0cf7295eea6d4d7242f8a9ea8e7791b Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Mon, 3 Jul 2023 09:32:54 +0530 Subject: [PATCH 19/20] added valid count check for import Signed-off-by: Yash Khare --- test/api/importcsv/api_test.go | 38 ++++++++++++++-------------------- 1 file changed, 16 insertions(+), 22 deletions(-) diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 0c3d5490e..2349e7fde 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -18,18 +18,26 @@ func TestImportCSV(t *testing.T) { inputData := api.ImportSummary{} assert.Must(t, Client.FilePost(api.UploadRoot, r.FileName, &inputData)) - // inject import summary id into Summary root + // Inject import summary id into Summary root pathForImportSummary := binding.Path(api.SummaryRoot).Inject(binding.Params{api.ID: inputData.ID}) // Since uploading the CSV happens asynchronously we need to wait for the upload to check Applications and Dependencies. time.Sleep(time.Second) - // Code below not working as expected need to check - - // checkImport := api.ImportSummary{} - // for checkImport.ValidCount + checkImport.InvalidCount != len(r.ExpectedApplications)+len(r.ExpectedDependencies){ - // assert.Should(t, Client.Get(pathForImportSummary, &checkImport)) - // } + var outputImportSummaries []api.ImportSummary + outputMatchingSummary := api.ImportSummary{} + for{ + assert.Should(t, Client.Get(api.SummariesRoot, &outputImportSummaries)) + for _, gotImport := range outputImportSummaries { + if uint(gotImport.ID) == inputData.ID { + outputMatchingSummary = gotImport + } + } + if(outputMatchingSummary.ValidCount + outputMatchingSummary.InvalidCount == len(r.ExpectedApplications)+len(r.ExpectedDependencies)){ + break + } + time.Sleep(time.Second) + } // Check list of Applications. gotApps, _ := Application.List() @@ -76,21 +84,7 @@ func TestImportCSV(t *testing.T) { t.Errorf("Mismatch in imported Dependency: Expected %s, Actual %s", r.ExpectedDependencies[i].From.Name, importedDep.From.Name) } } - } - - var outputImportSummaries []api.ImportSummary - outputMatchingSummary := api.ImportSummary{} - assert.Should(t, Client.Get(api.SummariesRoot, &outputImportSummaries)) - for _, imp := range outputImportSummaries { - if uint(imp.ID) == inputData.ID { - outputMatchingSummary = imp - } - } - - // Compare the number of imports. - if len(r.ExpectedApplications)+len(r.ExpectedDependencies) != outputMatchingSummary.ValidCount { - t.Errorf("Mismatch in no. of imports: expected %v, got %v", len(r.ExpectedApplications)+len(r.ExpectedDependencies), outputMatchingSummary.ValidCount) - } + } // Get summaries of the Input ID. outputImportSummary := api.ImportSummary{} From 128d807279a02cb6eb46f27aeb9c6d2ded9b7d6f Mon Sep 17 00:00:00 2001 From: Yash Khare Date: Mon, 3 Jul 2023 15:33:15 +0530 Subject: [PATCH 20/20] minor changes in the docs Signed-off-by: Yash Khare --- docs/test-api-matrix.md | 2 +- test/api/importcsv/api_test.go | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/test-api-matrix.md b/docs/test-api-matrix.md index 193551962..78fdaf1ce 100644 --- a/docs/test-api-matrix.md +++ b/docs/test-api-matrix.md @@ -7,7 +7,7 @@ application|:white_check_mark: partially|:heavy_check_mark:|| bucket||||partially within application dependency|:heavy_check_mark:|:heavy_check_mark:|:heavy_check_mark:| file|:heavy_check_mark:|:heavy_check_mark:|| -import||:heavy_check_mark:|:heavy_check_mark:| +import||:heavy_check_mark:|| review|||| **Controls**|||| businessservice|:heavy_check_mark:|:heavy_check_mark:|| diff --git a/test/api/importcsv/api_test.go b/test/api/importcsv/api_test.go index 2349e7fde..3e7776ec1 100644 --- a/test/api/importcsv/api_test.go +++ b/test/api/importcsv/api_test.go @@ -44,29 +44,29 @@ func TestImportCSV(t *testing.T) { if len(gotApps) != len(r.ExpectedApplications) { t.Errorf("Mismatch in number of imported Applications: Expected %d, Actual %d", len(r.ExpectedApplications), len(gotApps)) } else { - for i, importedApp := range gotApps { - if r.ExpectedApplications[i].Name != importedApp.Name { - t.Errorf("Mismatch in name of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Name, importedApp.Name) + for i, gotApp := range gotApps { + if r.ExpectedApplications[i].Name != gotApp.Name { + t.Errorf("Mismatch in name of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Name, gotApp.Name) } - if r.ExpectedApplications[i].Description != importedApp.Description { - t.Errorf("Mismatch in description of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Description, importedApp.Description) + if r.ExpectedApplications[i].Description != gotApp.Description { + t.Errorf("Mismatch in description of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Description, gotApp.Description) } - if r.ExpectedApplications[i].Repository.Kind != importedApp.Repository.Kind { - t.Errorf("Mismatch in repository's kind ofimported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Repository.Kind, importedApp.Repository.Kind) + if r.ExpectedApplications[i].Repository.Kind != gotApp.Repository.Kind { + t.Errorf("Mismatch in repository's kind ofimported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Repository.Kind, gotApp.Repository.Kind) } - if r.ExpectedApplications[i].Repository.URL != importedApp.Repository.URL { - t.Errorf("Mismatch in repository's url of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Repository.URL, importedApp.Repository.URL) + if r.ExpectedApplications[i].Repository.URL != gotApp.Repository.URL { + t.Errorf("Mismatch in repository's url of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Repository.URL, gotApp.Repository.URL) } - if r.ExpectedApplications[i].Binary != importedApp.Binary { - t.Errorf("Mismatch in binary of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Binary, importedApp.Binary) + if r.ExpectedApplications[i].Binary != gotApp.Binary { + t.Errorf("Mismatch in binary of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].Binary, gotApp.Binary) } for j, tag := range r.ExpectedApplications[i].Tags { - if tag.Name != importedApp.Tags[j].Name { - t.Errorf("Mismatch in tag name of imported Application: Expected %s, Actual %s", tag.Name, importedApp.Tags[j].Name) + if tag.Name != gotApp.Tags[j].Name { + t.Errorf("Mismatch in tag name of imported Application: Expected %s, Actual %s", tag.Name, gotApp.Tags[j].Name) } } - if r.ExpectedApplications[i].BusinessService.Name != importedApp.BusinessService.Name { - t.Errorf("Mismatch in name of the BusinessService of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].BusinessService.Name, importedApp.BusinessService.Name) + if r.ExpectedApplications[i].BusinessService.Name != gotApp.BusinessService.Name { + t.Errorf("Mismatch in name of the BusinessService of imported Application: Expected %s, Actual %s", r.ExpectedApplications[i].BusinessService.Name, gotApp.BusinessService.Name) } } }