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

Unit tests #1

Merged
merged 2 commits into from
Dec 2, 2019
Merged

Unit tests #1

merged 2 commits into from
Dec 2, 2019

Conversation

pop
Copy link
Contributor

@pop pop commented Nov 20, 2019

Unit Tests Initial Addition

The goal of this Pull Request is to add some basic "Happy Path" testing to the Golang SDK library.

While there are many refactors we are hoping to do in the coming weeks, this is just to create a baseline of test with minimal refactors to the actual API client.

Proposed changes

  • Add tests for each CloudBolt Client function.
    • New()
    • GetCloudBoltObject()
    • verifyGroup()
    • GetGroup()
    • DeployBlueprint()
    • GetOrder()
    • GetJob()
    • GetResource()
    • GetServer()
    • SubmitAction()
    • DecomOrder()
  • Include test data for those functions
  • Include some level of documentation about the tests and how to extend them.

Verifying this change

To verify these changes please check off the following boxes:

  • Run go test ./cbclient/ at the base of the repository.
    • Setup your go environment to use the latest version of Go (>=0.13.0).
    • Clone the respository.
    • The tests pass.
  • Review the changes to the code.

Administrivia

Everything below this line is just used for CloudBolt internal accounting.

Jira ID: DEV-12082

@pop pop mentioned this pull request Nov 22, 2019
5 tasks
This commit includes a bunch of unit tests that will make it much
easier to maintian and refactor the CloudBolt Go SDK going forward.

In addition to the new unit tests there are a few changes to the
API Client, really just code readability fixes.

Lastly, there are some Docs improvements and a rationale about the
what/why of our chosen tests design pattern.

The tests are far from complete. I hope to increase testing
coverage greatly when I have more cycles at my disposal.
Copy link

@nickbeaird nickbeaird left a comment

Choose a reason for hiding this comment

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

Feel free to take in my comments for now, and let's get your changes merged. I think that this looks great, and thank you for giving me time to start to review.

cbclient/api_client.go Show resolved Hide resolved
Self CloudBoltHALItem `json:"self"`
Owner CloudBoltHALItem `json:"owner"`
Parent CloudBoltHALItem `json:"parent"`
Subjobs []interface{} `json:"subjobs"`

Choose a reason for hiding this comment

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

I am not understanding why this interface is being used, or also how it is being used right now. I am looking at this article and seeing that the interfaces are a collection of methods, but I also see that it's set to an array. https://gobyexample.com/interfaces

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking around it seems like Subjobs should be a []CloudBoltHALItem so I'm going to make that change. Good catch!

@@ -107,37 +106,21 @@ type CloudBoltOrder struct {
} `json:"items"`
}

// CloudBoltJob contains metadata about a Job.
// Useful for getting the status of a running or completed job.
type CloudBoltJob struct {

Choose a reason for hiding this comment

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

I am comparing the CloudBoltJob to that of a job on ProdCIT. There seems to be differences. https://prodcit.lab.iad.cloudboltsw.com/api/v2/jobs/10302/

I will check in soon, so that I am not comparing apples to oranges.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I 💯 think there are discrepancies between the API Client and the API itself. I've made a story (DEV-14020) to go through all of the big-ticket items and make sure the go struct representations of our API objects reflect reality for some supported version of yet-to-be-decided supported CloudBolt version.

PowerOn struct {
Href string `json:"href"`
Title string `json:"title"`
} `json:"power_on,omitempty"`

Choose a reason for hiding this comment

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

I am wondering what is happening with these omitempty tags with an array. https://www.sohamkamani.com/blog/golang/2018-07-19-golang-omitempty/

OR
In reference to this post, is it that the array is empty, so it is not displayed? See the section "Values that Cannot be Ommitted"
golang/go#29310

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the blogpost, super helpful! My current theory is that I think this is actually a bug. The omitempty as it's written here will only have an effect when serializing the struct into JSON. For example, if Href and Title are empty ("") then PowerOn won't be included in the JSON output e.g., {"actions": [ ]}.
Now if we wanted to exclude this from the struct when de-serializing (parsing the JSON into a struct) we would want PowerOn to be a pointer. I got that from the section you pointed out "Values that Cannot be Omitted".

That's just a theory though and we'll want to experiment a bit before making any structural changes.

Choose a reason for hiding this comment

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

oh cool! Love it.

Group CloudBoltHALItem `json:"group"`
Owner CloudBoltHALItem `json:"owner"`
ApprovedBy CloudBoltHALItem `json:"approved-by"`
Actions CloudBoltHALItem `json:"actions"`

Choose a reason for hiding this comment

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

Looking at ProdCIT and my local, it looks like this can be an array, similar to Jobs below it.

https://prodcit.lab.iad.cloudboltsw.com/api/v2/orders/1/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very strange. I thought I'd actions as a HAL item, but looking around at our CIT and my personal CIT server it seems like every order follows this format:

        ... snip ...
        "actions": [
            {
                "duplicate": {
                    "href": "/api/v2/orders/##/actions/duplicate/",
                    "title": "Duplicate 'Order id ##'"
                }
            }
        ],
        ... snip ...

I'll fix that, it seems like a genuine bug in the implementation.

cbclient/testData.go Show resolved Hide resolved
cbclient/api_client_test.go Show resolved Hide resolved
Copy link
Contributor Author

@pop pop left a comment

Choose a reason for hiding this comment

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

Thanks @nickbeaird for bringing up a lot of awesome questions! I think you caught a few bugs that I can't wait to fix.

Since the focus of this PR was to keep things as unchanged as possible, and just test the client as is I would vote that we merge this PR and makes the bugfixes in #2.

Thoughts?

cbclient/testData.go Show resolved Hide resolved
PowerOn struct {
Href string `json:"href"`
Title string `json:"title"`
} `json:"power_on,omitempty"`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the blogpost, super helpful! My current theory is that I think this is actually a bug. The omitempty as it's written here will only have an effect when serializing the struct into JSON. For example, if Href and Title are empty ("") then PowerOn won't be included in the JSON output e.g., {"actions": [ ]}.
Now if we wanted to exclude this from the struct when de-serializing (parsing the JSON into a struct) we would want PowerOn to be a pointer. I got that from the section you pointed out "Values that Cannot be Omitted".

That's just a theory though and we'll want to experiment a bit before making any structural changes.

cbclient/api_client_test.go Show resolved Hide resolved
Group CloudBoltHALItem `json:"group"`
Owner CloudBoltHALItem `json:"owner"`
ApprovedBy CloudBoltHALItem `json:"approved-by"`
Actions CloudBoltHALItem `json:"actions"`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Very strange. I thought I'd actions as a HAL item, but looking around at our CIT and my personal CIT server it seems like every order follows this format:

        ... snip ...
        "actions": [
            {
                "duplicate": {
                    "href": "/api/v2/orders/##/actions/duplicate/",
                    "title": "Duplicate 'Order id ##'"
                }
            }
        ],
        ... snip ...

I'll fix that, it seems like a genuine bug in the implementation.

Self CloudBoltHALItem `json:"self"`
Owner CloudBoltHALItem `json:"owner"`
Parent CloudBoltHALItem `json:"parent"`
Subjobs []interface{} `json:"subjobs"`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking around it seems like Subjobs should be a []CloudBoltHALItem so I'm going to make that change. Good catch!

cbclient/api_client.go Show resolved Hide resolved
Self CloudBoltHALItem `json:"self"`
Parent CloudBoltHALItem `json:"parent"`
Subgroups []CloudBoltHALItem `json:"subgroups"`
Environments []interface{} `json:"environments"`
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should also be a []CloudBoltHALItem

@@ -107,37 +106,21 @@ type CloudBoltOrder struct {
} `json:"items"`
}

// CloudBoltJob contains metadata about a Job.
// Useful for getting the status of a running or completed job.
type CloudBoltJob struct {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I 💯 think there are discrepancies between the API Client and the API itself. I've made a story (DEV-14020) to go through all of the big-ticket items and make sure the go struct representations of our API objects reflect reality for some supported version of yet-to-be-decided supported CloudBolt version.

@pop pop merged commit 897e209 into master Dec 2, 2019
@pop pop deleted the unit-tests branch December 2, 2019 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants