Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
230 changes: 170 additions & 60 deletions cni/ipam/ipam_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Copy link
Contributor

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

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'm now using go-dep instead, adding github.com/onsi/ginkgo, github.com/onsi/gomega and gopkg.in/fsnotify.v1

. "github.com/onsi/gomega"
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 3rd party packages signed by microsoft legal (lca)

Copy link
Member

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


"github.com/Azure/azure-container-networking/common"
"github.com/Azure/azure-container-networking/platform"
)

var plugin *ipamPlugin

var ipamQueryUrl = "localhost:42424"
var ipamQueryResponse = "" +
"<Interfaces>" +
Expand All @@ -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() {

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() {

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

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?

Copy link
Contributor Author

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.

Copy link
Member

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

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

Choose a reason for hiding this comment

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

update description saying its delete call for ipam triggering release address

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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() {
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())
})
})
})
})
)
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ require (
github.com/hashicorp/golang-lru v0.5.3 // indirect
github.com/imdario/mergo v0.3.8 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect
github.com/onsi/ginkgo v1.12.0 // indirect
github.com/onsi/gomega v1.9.0 // indirect
github.com/onsi/ginkgo v1.12.0
github.com/onsi/gomega v1.9.0
github.com/petar/GoLLRB v0.0.0-20190514000832-33fb24c13b99 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/sirupsen/logrus v1.4.2 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.3 h1:YPkqC67at8FYaadspW/6uE0COsBxS2656RLEr8Bppgk=
github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.8 h1:CGgOkSJeqMRmt0D9XLWExdT4m4F1vd3FV3VPt+0VxkQ=
Expand Down Expand Up @@ -134,10 +135,12 @@ github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU=
github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
Expand Down Expand Up @@ -241,6 +244,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
Expand All @@ -256,9 +260,11 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
Expand Down
4 changes: 1 addition & 3 deletions ipam/azure.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,5 @@ func (s *azureSource) refresh() error {
}

// Set the local address space as active.
s.sink.setAddressSpace(local)

return nil
return s.sink.setAddressSpace(local)
}
Loading