-
Notifications
You must be signed in to change notification settings - Fork 260
Add IPAM unit tests && Using ginkgo replace the origin go test #508
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
Conversation
|
@tamilmani1989, @matmerr, @jaer-tsun. Hi all, I'm an SWE Intern to ASK China team. My leader and mentor want me to be familiar with Azure CNI, and add some unit tests for it. So I mentioned this PR after learning the code of Azure CNI. This PR mainly adds some unit tests of IPAM to ensure that each function can get the expected results. To make the test code look clearer, I used ginkgo as the unit test framework. I hope you can spare time to review my PR. If there is any problem, I will correct it in time. You can also connect me on Teams, my alias is t-yuqian :) At present, I am adding unit tests for the network package. |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
ipam/null.go
Outdated
|
|
||
| // Set the local address space as active. | ||
| s.sink.setAddressSpace(local) | ||
| if err := s.sink.setAddressSpace(local); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return s.sink.setAddressSpace(local)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get
| "github.com/Azure/azure-container-networking/platform" | ||
| cniSkel "github.com/containernetworking/cni/pkg/skel" | ||
| cniTypesCurr "github.com/containernetworking/cni/pkg/types/current" | ||
| . "github.com/onsi/ginkgo" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't use submodules in this repo so please vendor via go-dep
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm now using go-dep instead, adding github.com/onsi/ginkgo, github.com/onsi/gomega and gopkg.in/fsnotify.v1
cni/ipam/ipam_test.go
Outdated
| testAgent, err := common.NewListener(u) | ||
| func parseResult(stdinData []byte) (*cniTypesCurr.Result, error) { | ||
| result := &cniTypesCurr.Result{} | ||
| err := json.Unmarshal(stdinData, result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for single returns, current style is to keep it on the same line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Get, thanks!
cni/ipam/ipam_test.go
Outdated
| _ = Describe("Test IPAM", func() { | ||
|
|
||
| var ( | ||
| config common.PluginConfig |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like linter didn't work here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will move config to the Context where it works
ipam/azure_test.go
Outdated
|
|
||
| func parseResult(stdinData []byte) (*cniTypesCurr.Result, error) { | ||
| result := &cniTypesCurr.Result{} | ||
| err := json.Unmarshal(stdinData, result) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current style is to merge with if statement for single returns
e.g.
if err := json.Marshal...; err != nil {
...
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, thanks!
ipam/fileIpam_test.go
Outdated
| Scope: scope, | ||
| Pools: make(map[string]*addressPool), | ||
| }, nil | ||
| } else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for else block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll remove it
ipam/fileIpam_test.go
Outdated
| options[common.OptEnvironment] = common.OptEnvironmentFileIpam | ||
| fileIpam, _ := newFileIpamSource(options) | ||
| type addressManagerMock struct { | ||
| newAddressSpaceSucc bool |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type out Succ
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok!
ipam/fileIpam_test.go
Outdated
| func (sink *addressManagerMock) setAddressSpace(*addressSpace) error { | ||
| if sink.setAddressSpaceSucc { | ||
| return nil | ||
| } else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need for else block
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll remove it
tamilmani1989
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. Reviewed half. will review remaining later. One concern is that description of each test case. its little confusing if its pool or address
cni/ipam/ipam_test.go
Outdated
| } | ||
| func getStdinData(cniversion, ifname, subnet, ipAddress string) []byte { | ||
| stdinData := fmt.Sprintf( | ||
| `{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
space damage
cni/ipam/ipam_test.go
Outdated
| fmt.Printf("Failed to create IPAM plugin, err:%v.\n", err) | ||
| return | ||
| } | ||
| func getIfName() (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need this ? What this function expected to return? I think this is for pod interface name right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I copy this code from network.go, for getting the interface name of the test environment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about just using a fake interface name, say eth0, for simplicity? We'll not setup and configure an interface, anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In cni/network/network.go 145, it will detect the in used interface name. For network.go get the same interface name as the test code, I added this function...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the problem is if there are multiple interfaces, if it returns lo adapter or docker0 bridge as 1st interface, then this will break. for simplicity you can keep it as eth0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank @DancingLinks for your clarification.
the problem is if there are multiple interfaces, if it returns lo adapter or docker0 bridge as 1st interface, then this will break. for simplicity you can keep it as eth0
After re-reading the code, @DancingLinks and I found that we do not have an interface check, so both lo and docker0 will still work. But in practise, lo and docker0 will not be picked for mac address mismatch.
Also, I found that interface name is not specified for the Kubernetes case[1]. How about we first cover the path without an interface name when invoking the IPAM plugin.
If we have to select a real interface name, how about removing lo and docker0 from the interface list and pick one randomly, in case we may have interface names other than eth0, in different OS releases? This seems to be more real.
| var result *cniTypesCurr.Result | ||
|
|
||
| Context("When ADD with nothing (request pool)", func() { | ||
| It("Request pool and ADD successfully", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this for request pool or request address or for both?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both. I found that this case may happen when request pool.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then update description saying this is test for ipam add call
Gopkg.toml
Outdated
| # go-tests = true | ||
| # unused-packages = true | ||
|
|
||
| [[override]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is this package for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When I run dep ensure, an error occurred.
golang/dep#1799
cloudfoundry/disaster-recovery-acceptance-tests@983620d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this signed off by lca?
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
jaer-tsun
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, waiting on @tamilmani1989 final review
mainred
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your commits. Please remove Submodule.
ipam/azure_test.go
Outdated
| }) | ||
| }) | ||
| }) | ||
| ) No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need a newline here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'll add a newline here :) forgot
cni/ipam/ipam_test.go
Outdated
| fmt.Printf("Failed to create IPAM plugin, err:%v.\n", err) | ||
| return | ||
| } | ||
| func getIfName() (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about just using a fake interface name, say eth0, for simplicity? We'll not setup and configure an interface, anyway.
cni/ipam/ipam_test.go
Outdated
|
|
||
| Context("When address and subnet is given", func() { | ||
| It("ADD address successfully with the given address", func() { | ||
| arg.StdinData = getStdinData("0.4.0", ifName, "10.0.0.0/16", "10.0.0.6") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about using another CIDR instead of the default one 10.0.0.0/16? So that we can test the returned IP address is not from the default CIDR.
ipam/manager_test.go
Outdated
| "testing" | ||
|
|
||
| "github.com/Azure/azure-container-networking/common" | ||
| "time" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The following package groups sequence convention is very popular:
- standard library
- third-party packages
- local packages
Could you please adjust your code to comply with this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my only concern with 3rd party is we have to get approval from lca before using that..did we get required approval?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much for pointing this out. I am not sure about the newly imported packages in this PR.
I saw from our Golang files that we are using different package group conventions, so I here just want to share my idea to follow one convention.
cni/ipam/ipam_test.go
Outdated
| err error | ||
| ) | ||
|
|
||
| BeforeSuite(func() { |
There was a problem hiding this comment.
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 am wrong, BeforeSuite and AfterSuite is suitable to be outside of the Describe clause as suite-scoped resources.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll move them outside of the Describe, thx!
tamilmani1989
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for this PR. Really appreciate the effort. Left some comments
Gopkg.toml
Outdated
| # go-tests = true | ||
| # unused-packages = true | ||
|
|
||
| [[override]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this signed off by lca?
| cniSkel "github.com/containernetworking/cni/pkg/skel" | ||
| cniTypesCurr "github.com/containernetworking/cni/pkg/types/current" | ||
| . "github.com/onsi/ginkgo" | ||
| . "github.com/onsi/gomega" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are these 3rd party packages signed by microsoft legal (lca)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about this, but we have these two packages used in repos like aks-engine already.
https://github.com/search?q=org%3AAzure+github.com%2Fonsi%2Fginkgo&type=Code
cni/ipam/ipam_test.go
Outdated
| fmt.Printf("Failed to create IPAM plugin, err:%v.\n", err) | ||
| return | ||
| } | ||
| func getIfName() (string, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the problem is if there are multiple interfaces, if it returns lo adapter or docker0 bridge as 1st interface, then this will break. for simplicity you can keep it as eth0
| var result *cniTypesCurr.Result | ||
|
|
||
| Context("When ADD with nothing (request pool)", func() { | ||
| It("Request pool and ADD successfully", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then update description saying this is test for ipam add call
ipam/azure_test.go
Outdated
| }) | ||
| }) | ||
|
|
||
| Context("When time interval is less", func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
couldnot understand what this test for..what we are testing here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Neither can I. Let's remove this test unless you can make it more descriptive and please also remember test will also be maintained as part of our code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will change the description as "refresh interval is too short". It may be more clearly now.
ipam/azure_test.go
Outdated
|
|
||
| Context("When newAddressSpace err", func() { | ||
| It("Exit with error when refresh", func() { | ||
| sink := &addressManagerMock{false, true} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what this mock does..can you add a comment ..is addressmanagermock defined somewhere
ipam/manager_test.go
Outdated
| "testing" | ||
|
|
||
| "github.com/Azure/azure-container-networking/common" | ||
| "time" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my only concern with 3rd party is we have to get approval from lca before using that..did we get required approval?
| RefCount: 1, | ||
| Addresses: make(map[string]*addressRecord), | ||
| } | ||
| ap.Addresses["ar-test"] = &addressRecord{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we also add some addr and check if addrbyid returns that address...thats the main purpose of addrsbyid
| t.Errorf("ReleasePool failed, err:%v", err) | ||
| } | ||
| } | ||
| var ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was unit test for requestpool, requestaddr, releaseddr, releasepool moved somewhere else?
mainred
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM from my part, but please let @tamilmani1989 make the decision.
|
@DancingLinks Can you rebase and push it again? |
|
@DancingLinks, besides rebasing your code, could you please also squash your commits and reword your commit messages to explain your changes neatly before we merge this PR? |
|
@tamilmani1989 rebased finished :) |
|
@mainred Thanks a lot for your suggestion! I've now merged them in a single commit. |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
2. Using ginkgo instead of the origin go test
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
tamilmani1989
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
What this PR does / why we need it:
Which issue this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)format, will close that issue when PR gets merged): fixes #Special notes for your reviewer:
Release note: