-
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4,17 +4,21 @@ | |
| package ipam | ||
|
|
||
| import ( | ||
| "encoding/json" | ||
| "fmt" | ||
| "net/http" | ||
| "net/url" | ||
| "os" | ||
| "testing" | ||
|
|
||
| cniSkel "github.com/containernetworking/cni/pkg/skel" | ||
| cniTypesCurr "github.com/containernetworking/cni/pkg/types/current" | ||
| . "github.com/onsi/ginkgo" | ||
| . "github.com/onsi/gomega" | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are these 3rd party packages signed by microsoft legal (lca)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. |
||
|
|
||
| "github.com/Azure/azure-container-networking/common" | ||
| "github.com/Azure/azure-container-networking/platform" | ||
| ) | ||
|
|
||
| var plugin *ipamPlugin | ||
|
|
||
| var ipamQueryUrl = "localhost:42424" | ||
| var ipamQueryResponse = "" + | ||
| "<Interfaces>" + | ||
|
|
@@ -27,70 +31,176 @@ var ipamQueryResponse = "" + | |
| " </Interface>" + | ||
| "</Interfaces>" | ||
|
|
||
| var localAsId string | ||
| var poolId1 string | ||
| var address1 string | ||
|
|
||
| // Wraps the test run with plugin setup and teardown. | ||
| func TestMain(m *testing.M) { | ||
| var config common.PluginConfig | ||
|
|
||
| // Create a fake local agent to handle requests from IPAM plugin. | ||
| u, _ := url.Parse("tcp://" + ipamQueryUrl) | ||
| testAgent, err := common.NewListener(u) | ||
| if err != nil { | ||
| fmt.Printf("Failed to create agent, err:%v.\n", err) | ||
| return | ||
| } | ||
| testAgent.AddHandler("/", handleIpamQuery) | ||
|
|
||
| err = testAgent.Start(make(chan error, 1)) | ||
| if err != nil { | ||
| fmt.Printf("Failed to start agent, err:%v.\n", err) | ||
| return | ||
| } | ||
|
|
||
| // Create the plugin. | ||
| plugin, err = NewPlugin("ipamtest", &config) | ||
| if err != nil { | ||
| fmt.Printf("Failed to create IPAM plugin, err:%v.\n", err) | ||
| return | ||
| } | ||
|
|
||
| // Configure test mode. | ||
| plugin.SetOption(common.OptEnvironment, common.OptEnvironmentAzure) | ||
| plugin.SetOption(common.OptAPIServerURL, "null") | ||
| plugin.SetOption(common.OptIpamQueryUrl, "http://"+ipamQueryUrl) | ||
|
|
||
| // Start the plugin. | ||
| err = plugin.Start(&config) | ||
| if err != nil { | ||
| fmt.Printf("Failed to start IPAM plugin, err:%v.\n", err) | ||
| return | ||
| } | ||
|
|
||
| // Run tests. | ||
| exitCode := m.Run() | ||
|
|
||
| // Cleanup. | ||
| plugin.Stop() | ||
| testAgent.Stop() | ||
|
|
||
| os.Exit(exitCode) | ||
| func TestIpam(t *testing.T) { | ||
| RegisterFailHandler(Fail) | ||
| RunSpecs(t, "Ipam Suite") | ||
| } | ||
|
|
||
| // Handles queries from IPAM source. | ||
| func handleIpamQuery(w http.ResponseWriter, r *http.Request) { | ||
| w.Write([]byte(ipamQueryResponse)) | ||
| } | ||
|
|
||
| // | ||
| // CNI IPAM API compliance tests | ||
| // https://github.com/containernetworking/cni/blob/master/SPEC.md | ||
| // | ||
|
|
||
| func TestAddSuccess(t *testing.T) { | ||
| func parseResult(stdinData []byte) (*cniTypesCurr.Result, error) { | ||
| result := &cniTypesCurr.Result{} | ||
| if err := json.Unmarshal(stdinData, result); err != nil { | ||
| return nil, err | ||
| } | ||
| return result, nil | ||
| } | ||
|
|
||
| func TestDelSuccess(t *testing.T) { | ||
| func getStdinData(cniversion, subnet, ipAddress string) []byte { | ||
| stdinData := fmt.Sprintf( | ||
| `{ | ||
| "cniversion": "%s", | ||
| "ipam": { | ||
| "type": "internal", | ||
| "subnet": "%s", | ||
| "ipAddress": "%s" | ||
| } | ||
| }`, cniversion, subnet, ipAddress) | ||
| return []byte(stdinData) | ||
| } | ||
|
|
||
| var ( | ||
|
|
||
| plugin *ipamPlugin | ||
| testAgent *common.Listener | ||
| arg *cniSkel.CmdArgs | ||
| err error | ||
|
|
||
| _ = BeforeSuite(func() { | ||
| // Create a fake local agent to handle requests from IPAM plugin. | ||
| u, _ := url.Parse("tcp://" + ipamQueryUrl) | ||
| testAgent, err = common.NewListener(u) | ||
| Expect(err).NotTo(HaveOccurred()) | ||
|
|
||
| testAgent.AddHandler("/", handleIpamQuery) | ||
|
|
||
| err = testAgent.Start(make(chan error, 1)) | ||
| Expect(err).NotTo(HaveOccurred()) | ||
|
|
||
| arg = &cniSkel.CmdArgs{} | ||
| }) | ||
|
|
||
| _ = AfterSuite(func() { | ||
| // Cleanup. | ||
| plugin.Stop() | ||
| testAgent.Stop() | ||
| }) | ||
|
|
||
| _ = Describe("Test IPAM", func() { | ||
|
|
||
| Context("IPAM start", func() { | ||
DancingLinks marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| var config common.PluginConfig | ||
|
|
||
| It("Create IPAM plugin", func() { | ||
| // Create the plugin. | ||
| plugin, err = NewPlugin("ipamtest", &config) | ||
| Expect(err).NotTo(HaveOccurred()) | ||
| }) | ||
|
|
||
| It("Start IPAM plugin", func() { | ||
| // Configure test mode. | ||
| plugin.SetOption(common.OptEnvironment, common.OptEnvironmentAzure) | ||
| plugin.SetOption(common.OptAPIServerURL, "null") | ||
| plugin.SetOption(common.OptIpamQueryUrl, "http://"+ipamQueryUrl) | ||
| // Start the plugin. | ||
| err = plugin.Start(&config) | ||
| Expect(err).NotTo(HaveOccurred()) | ||
| }) | ||
| }) | ||
|
|
||
| Describe("Test IPAM ADD and DELETE pool", func() { | ||
DancingLinks marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| var result *cniTypesCurr.Result | ||
|
|
||
| Context("When ADD with nothing, call for ipam triggering request pool and address", func() { | ||
| It("Request pool and ADD successfully", func() { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this for request pool or request address or for both?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Both. I found that this case may happen when request pool.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then update description saying this is test for ipam add call |
||
| arg.StdinData = getStdinData("0.4.0", "", "") | ||
| err = plugin.Add(arg) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| result, err = parseResult(arg.StdinData) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| address1, _ := platform.ConvertStringToIPNet("10.0.0.5/16") | ||
| address2, _ := platform.ConvertStringToIPNet("10.0.0.6/16") | ||
DancingLinks marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Expect(result.IPs[0].Address.IP).Should(Or(Equal(address1.IP), Equal(address2.IP))) | ||
| Expect(result.IPs[0].Address.Mask).Should(Equal(address1.Mask)) | ||
| }) | ||
| }) | ||
|
|
||
| Context("When DELETE with subnet and address, call for ipam triggering release address", func() { | ||
| It("DELETE address successfully", func() { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. update description saying its delete call for ipam triggering release address
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. finished |
||
| arg.StdinData = getStdinData("0.4.0", "10.0.0.0/16", result.IPs[0].Address.IP.String()) | ||
| err = plugin.Delete(arg) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| }) | ||
| }) | ||
|
|
||
| Context("When DELETE with subnet, call for ipam triggering releasing pool", func() { | ||
| It("DELETE pool successfully", func() { | ||
| arg.StdinData = getStdinData("0.4.0", "10.0.0.0/16", "") | ||
| err = plugin.Delete(arg) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| }) | ||
| }) | ||
| }) | ||
|
|
||
| Describe("Test IPAM ADD and DELETE address", func() { | ||
|
|
||
| Context("When address is given", func() { | ||
| It("Request pool and address successfully", func() { | ||
| arg.StdinData = getStdinData("0.4.0", "", "10.0.0.6") | ||
| err = plugin.Add(arg) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| result, err := parseResult(arg.StdinData) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| address, _ := platform.ConvertStringToIPNet("10.0.0.6/16") | ||
| Expect(result.IPs[0].Address.IP).Should(Equal(address.IP)) | ||
| Expect(result.IPs[0].Address.Mask).Should(Equal(address.Mask)) | ||
| }) | ||
| }) | ||
|
|
||
| Context("When subnet is given", func() { | ||
| It("Request a usable address successfully", func() { | ||
| arg.StdinData = getStdinData("0.4.0", "10.0.0.0/16", "") | ||
| err = plugin.Add(arg) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| result, err := parseResult(arg.StdinData) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| address, _ := platform.ConvertStringToIPNet("10.0.0.5/16") | ||
| Expect(result.IPs[0].Address.IP).Should(Equal(address.IP)) | ||
| Expect(result.IPs[0].Address.Mask).Should(Equal(address.Mask)) | ||
| }) | ||
| }) | ||
| }) | ||
|
|
||
| Describe("Test IPAM DELETE", func() { | ||
|
|
||
| Context("When address and subnet is given", func() { | ||
DancingLinks marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| It("Release address successfully", func() { | ||
| arg.StdinData = getStdinData("0.4.0", "10.0.0.0/16", "10.0.0.5") | ||
| err = plugin.Delete(arg) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| }) | ||
| }) | ||
|
|
||
| Context("When address and subnet is given", func() { | ||
| It("Release address successfully", func() { | ||
| arg.StdinData = getStdinData("0.4.0", "10.0.0.0/16", "10.0.0.6") | ||
| err = plugin.Delete(arg) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| }) | ||
| }) | ||
|
|
||
| Context("When subnet is given", func() { | ||
| It("Release pool successfully", func() { | ||
| arg.StdinData = getStdinData("0.4.0", "10.0.0.0/16", "") | ||
| err = plugin.Delete(arg) | ||
| Expect(err).ShouldNot(HaveOccurred()) | ||
| }) | ||
| }) | ||
| }) | ||
| }) | ||
| ) | ||
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