Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🌱 add csv import test #390

Merged
merged 22 commits into from
Jul 3, 2023
Merged

🌱 add csv import test #390

merged 22 commits into from
Jul 3, 2023

Conversation

khareyash05
Copy link
Contributor

@khareyash05 khareyash05 commented Jun 13, 2023

Closes #388

Work Done as of now

  1. Created a sample of data to be passed in samples.go
  2. Initialized RichClient.Client
  3. Uploaded CSV using FilePost
  4. Get contents of /importsummaries
  5. Compare Applications and Dependencies with the output of the API
  6. Compare valid count with no. of Applications and Dependencies
  7. Added checks for all routes
  8. Download the CSV
  9. Compare informations of CSV's

Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
@khareyash05 khareyash05 changed the title add csv import test 🌱 add csv import test Jun 13, 2023
@aufi aufi self-assigned this Jun 13, 2023
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Copy link
Member

@aufi aufi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice start, Yash! Added few comments primary on naming. About extending the client.go with file upload, there is a PR #393 updating FileSend, let's see if it is useful also for this purpose once it gets merged (will review then).

Looking forward to update checking of Imports status and created resources to find all things needed that need to be tested there.

test/api/importCSV/api_test.go Outdated Show resolved Hide resolved
test/api/importCSV/api_test.go Outdated Show resolved Hide resolved
test/api/importCSV/samples.go Outdated Show resolved Hide resolved
test/api/importCSV/api_test.go Outdated Show resolved Hide resolved
@khareyash05
Copy link
Contributor Author

Nice start, Yash! Added few comments primary on naming. About extending the client.go with file upload, there is a PR #393 updating FileSend, let's see if it is useful also for this purpose once it gets merged (will review then).

Looking forward to update checking of Imports status and created resources to find all things needed that need to be tested there.

Thanks Marek. Ya I went through the PR and seems to me that merging it will cause merge conflicts. Better to wait.
As for update checking I am figuring out a few things and will update them as soon as the it is done. Thank you for the review.

Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
@khareyash05 khareyash05 requested a review from aufi June 16, 2023 11:58
@khareyash05
Copy link
Contributor Author

Added comparison logic for applications and dependencies with the expected API output

@khareyash05 khareyash05 marked this pull request as ready for review June 16, 2023 14:24
Copy link
Member

@aufi aufi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good progress, added few comments.

var (
TestCases = []TestCase{
{
fileName: "template_application_import.csv",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about fileName vs. FileName.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any specific reference to this name change? Because I found UploadCSV() using fileName, thatswhy named the same

TestCases = []TestCase{
{
fileName: "template_application_import.csv",
ExpectedApplications: []api.Application{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This array looks good, please go ahead and add Application fields data from the CSV.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the data in this CSV is supposed to be equivalent to what is being described in the template_application_import.csv?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the data in this CSV is supposed to be equivalent to what is being described in the template_application_import.csv?

Ya even I think so because we are checking that if all the entities are being uploaded or not thus have to check them all

expectedApps := r.ExpectedApplications
expectedDeps := r.ExpectedDependencies
importList, ok := imports.([]interface{})
if ok {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look to API source code, there is ImportSummary struct as well as Import struct which is a middle step between Import CSV and created Applications (https://github.com/konveyor/tackle2-hub/blob/main/api/import.go#L271-L289 and processed in https://github.com/konveyor/tackle2-hub/blob/main/importer/manager.go#L51).

Try to check Applications directly with application.List() and fields on ImportSummary like count of valid records imported.

Generaly, it is always good to check the source code and the feature that is being tested to find out how it works, identify what might make sense to be checked (in addition to fields of an Applications/Dependencies) and since go is a static language, we should utilize its advantages, so use interfaces/casting only in necessary situations.

@khareyash05 khareyash05 marked this pull request as draft June 23, 2023 10:40
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
@khareyash05 khareyash05 requested a review from aufi June 25, 2023 11:24
Copy link
Member

@aufi aufi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for update! See comments inline + try follow similar conventions as in previous dependency test, e.g. when creating paths for API request, use consts from API package instead of hardcoding paths in string (details inline).

binding/client.go Outdated Show resolved Hide resolved
@@ -368,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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please correct me if I'm wrong, but the changes related to putFile -> loadFile methods doesn't seem to be needed since you created FilePost method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We had actually changed the name of the function from putFile to loadFile to make it generic. Thus updated the same everywhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood, but this change came in time when there was another function calling the loadFile, which is gone since you added FilePost method (which is a better solution for this). So the putFile is called only from BucketPut, so I'd would not recommend changing it (as actually unrelated code to this test/PR).

test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
test/api/importcsv/api_test.go Outdated Show resolved Hide resolved

// Check list of Dependencies.
importedDeps, _ := Dependency.List()
expectedDeps := r.ExpectedDependencies
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these expectedDeps&expectedApps needed, wouldn't be better use r.Expected... variables?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do that.

test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
test/api/importcsv/api_test.go Show resolved Hide resolved
test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
@@ -368,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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood, but this change came in time when there was another function calling the loadFile, which is gone since you added FilePost method (which is a better solution for this). So the putFile is called only from BucketPut, so I'd would not recommend changing it (as actually unrelated code to this test/PR).

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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These assertions return true/false, but actually do nothing with the test result. Please look to the FlatEqual method body and to your previous PR to its usage (e.g. https://github.com/konveyor/tackle2-hub/blob/main/test/api/dependency/api_test.go#L34-L36)

In some cases, it might be better use == instead of FlatEqual function (expectedApps[i].Name, importedApp.Name => if expectedApps[i].Name != importedApp.Name {error...})

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do that!


// Upload CSV.
inputData := api.ImportSummary{}
assert.Must(t, Client.FilePost(api.SummariesRoot+"/upload", r.FileName, &inputData))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the right way creating the path, please follow what you had in your previous PR https://github.com/konveyor/tackle2-hub/pull/375/files#diff-6ded4e5e60480daa4db7cf0740809d6b470d937e85d1b674b02777560fed1a38R25

Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
To *Application `gorm:"foreignKey:ToID;constraint:OnDelete:CASCADE"`
FromID uint `gorm:"index"`
FromID uint `gorm:"uniqueIndex:dependency_primary_key"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Appreciate your effort on looking thi issue, but it cannot be in this PR with tests. Please create a new one referencing to reported issue and look on notes below.

  • the schema is versioned, it is needed create new version (or modify the latest one if it was not released yet - I'm not sure if it is possible now, let's see on the new PR)
  • I'm not sure about using "primary_key" as part of name of composite uniq key, would you consider a more descriptive name?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surely ! Will address it in the next PR

Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
@khareyash05 khareyash05 requested a review from aufi June 29, 2023 14:16
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
}

// Compare each value.
for i := 0; i < len(item1); i++ {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to see such precise file content diff check (byte by byte), but it might be easier/more matching to the test/better to read both files data, cast []byte to string and compare it and in case of error, print both contents got and expected, that will be much easier to debug why a test potentialy failed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will work on that.Thanks Marek

Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
@khareyash05 khareyash05 marked this pull request as ready for review June 30, 2023 03:31
@khareyash05 khareyash05 requested a review from aufi June 30, 2023 03:31
Copy link
Member

@aufi aufi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for update Yash! Added few comments, please look on them.

@@ -21,7 +21,7 @@ import (
pathlib "path"
"path/filepath"
"strings"
"time"
"time"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit, but not needed change, please remove trailing spaces.

docs/test-api-matrix.md Outdated Show resolved Hide resolved
test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we discussed a loop waiting for importsummary until it get process all records (e.g. sleep 1 sec, get importsummary and if valid+invalid count is equal to all application&dependencies count, break from the loop and continue).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a blocker, just for info.

test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedApps[j].BusinessService.Name, imp["businessService"])
}
j++
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIUC, shouldn't there be a second part of the condition - if outputImports has more records than expectedApps, the test should fail too. Same for dependencies few lines below.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

outputimports consist of both applications and dependencies thus shouldn't be equal to length of sums?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the CSV for this test would get one more line with an application, but the test (expected applications) was not changed (=> more imports type 1, but not changed len(expectedApps)), it looks to me to pass this part of the test anywa - that was the thing I didn't like. On the other hand there is a check of gotApps len() on line 44 and in this PR we don't have to do deeper rejection tests, so it is likely OK.

test/api/importcsv/api_test.go Show resolved Hide resolved
test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
test/api/importcsv/api_test.go Show resolved Hide resolved
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
Copy link
Member

@aufi aufi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left few minor comments, but looks good to me.

docs/test-api-matrix.md Outdated Show resolved Hide resolved
test/api/importcsv/api_test.go Outdated Show resolved Hide resolved
t.Errorf("Mismatch in name of import: Expected %s, Actual %s", expectedApps[j].BusinessService.Name, imp["businessService"])
}
j++
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the CSV for this test would get one more line with an application, but the test (expected applications) was not changed (=> more imports type 1, but not changed len(expectedApps)), it looks to me to pass this part of the test anywa - that was the thing I didn't like. On the other hand there is a check of gotApps len() on line 44 and in this PR we don't have to do deeper rejection tests, so it is likely OK.

Signed-off-by: Yash Khare <yash2010118@akgec.ac.in>
@aufi
Copy link
Member

aufi commented Jul 3, 2023

Part of konveyor/operator#220

@aufi aufi merged commit f8f1e0d into konveyor:main Jul 3, 2023
9 checks passed
@aufi aufi added the test/api Hub API tests-related work label Jul 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
test/api Hub API tests-related work
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add CSV Application Import test
3 participants