44package ipam
55
66import (
7+ "encoding/json"
78 "fmt"
89 "net/http"
910 "net/url"
10- "os"
1111 "testing"
1212
13+ cniSkel "github.com/containernetworking/cni/pkg/skel"
14+ cniTypesCurr "github.com/containernetworking/cni/pkg/types/current"
15+ . "github.com/onsi/ginkgo"
16+ . "github.com/onsi/gomega"
17+
1318 "github.com/Azure/azure-container-networking/common"
19+ "github.com/Azure/azure-container-networking/platform"
1420)
1521
16- var plugin * ipamPlugin
17-
1822var ipamQueryUrl = "localhost:42424"
1923var ipamQueryResponse = "" +
2024 "<Interfaces>" +
@@ -27,70 +31,176 @@ var ipamQueryResponse = "" +
2731 " </Interface>" +
2832 "</Interfaces>"
2933
30- var localAsId string
31- var poolId1 string
32- var address1 string
33-
34- // Wraps the test run with plugin setup and teardown.
35- func TestMain (m * testing.M ) {
36- var config common.PluginConfig
37-
38- // Create a fake local agent to handle requests from IPAM plugin.
39- u , _ := url .Parse ("tcp://" + ipamQueryUrl )
40- testAgent , err := common .NewListener (u )
41- if err != nil {
42- fmt .Printf ("Failed to create agent, err:%v.\n " , err )
43- return
44- }
45- testAgent .AddHandler ("/" , handleIpamQuery )
46-
47- err = testAgent .Start (make (chan error , 1 ))
48- if err != nil {
49- fmt .Printf ("Failed to start agent, err:%v.\n " , err )
50- return
51- }
52-
53- // Create the plugin.
54- plugin , err = NewPlugin ("ipamtest" , & config )
55- if err != nil {
56- fmt .Printf ("Failed to create IPAM plugin, err:%v.\n " , err )
57- return
58- }
59-
60- // Configure test mode.
61- plugin .SetOption (common .OptEnvironment , common .OptEnvironmentAzure )
62- plugin .SetOption (common .OptAPIServerURL , "null" )
63- plugin .SetOption (common .OptIpamQueryUrl , "http://" + ipamQueryUrl )
64-
65- // Start the plugin.
66- err = plugin .Start (& config )
67- if err != nil {
68- fmt .Printf ("Failed to start IPAM plugin, err:%v.\n " , err )
69- return
70- }
71-
72- // Run tests.
73- exitCode := m .Run ()
74-
75- // Cleanup.
76- plugin .Stop ()
77- testAgent .Stop ()
78-
79- os .Exit (exitCode )
34+ func TestIpam (t * testing.T ) {
35+ RegisterFailHandler (Fail )
36+ RunSpecs (t , "Ipam Suite" )
8037}
8138
8239// Handles queries from IPAM source.
8340func handleIpamQuery (w http.ResponseWriter , r * http.Request ) {
8441 w .Write ([]byte (ipamQueryResponse ))
8542}
8643
87- //
88- // CNI IPAM API compliance tests
89- // https://github.com/containernetworking/cni/blob/master/SPEC.md
90- //
91-
92- func TestAddSuccess ( t * testing. T ) {
44+ func parseResult ( stdinData [] byte ) ( * cniTypesCurr. Result , error ) {
45+ result := & cniTypesCurr. Result {}
46+ if err := json . Unmarshal ( stdinData , result ); err != nil {
47+ return nil , err
48+ }
49+ return result , nil
9350}
9451
95- func TestDelSuccess (t * testing.T ) {
52+ func getStdinData (cniversion , subnet , ipAddress string ) []byte {
53+ stdinData := fmt .Sprintf (
54+ `{
55+ "cniversion": "%s",
56+ "ipam": {
57+ "type": "internal",
58+ "subnet": "%s",
59+ "ipAddress": "%s"
60+ }
61+ }` , cniversion , subnet , ipAddress )
62+ return []byte (stdinData )
9663}
64+
65+ var (
66+
67+ plugin * ipamPlugin
68+ testAgent * common.Listener
69+ arg * cniSkel.CmdArgs
70+ err error
71+
72+ _ = BeforeSuite (func () {
73+ // Create a fake local agent to handle requests from IPAM plugin.
74+ u , _ := url .Parse ("tcp://" + ipamQueryUrl )
75+ testAgent , err = common .NewListener (u )
76+ Expect (err ).NotTo (HaveOccurred ())
77+
78+ testAgent .AddHandler ("/" , handleIpamQuery )
79+
80+ err = testAgent .Start (make (chan error , 1 ))
81+ Expect (err ).NotTo (HaveOccurred ())
82+
83+ arg = & cniSkel.CmdArgs {}
84+ })
85+
86+ _ = AfterSuite (func () {
87+ // Cleanup.
88+ plugin .Stop ()
89+ testAgent .Stop ()
90+ })
91+
92+ _ = Describe ("Test IPAM" , func () {
93+
94+ Context ("IPAM start" , func () {
95+
96+ var config common.PluginConfig
97+
98+ It ("Create IPAM plugin" , func () {
99+ // Create the plugin.
100+ plugin , err = NewPlugin ("ipamtest" , & config )
101+ Expect (err ).NotTo (HaveOccurred ())
102+ })
103+
104+ It ("Start IPAM plugin" , func () {
105+ // Configure test mode.
106+ plugin .SetOption (common .OptEnvironment , common .OptEnvironmentAzure )
107+ plugin .SetOption (common .OptAPIServerURL , "null" )
108+ plugin .SetOption (common .OptIpamQueryUrl , "http://" + ipamQueryUrl )
109+ // Start the plugin.
110+ err = plugin .Start (& config )
111+ Expect (err ).NotTo (HaveOccurred ())
112+ })
113+ })
114+
115+ Describe ("Test IPAM ADD and DELETE pool" , func () {
116+
117+ var result * cniTypesCurr.Result
118+
119+ Context ("When ADD with nothing, call for ipam triggering request pool and address" , func () {
120+ It ("Request pool and ADD successfully" , func () {
121+ arg .StdinData = getStdinData ("0.4.0" , "" , "" )
122+ err = plugin .Add (arg )
123+ Expect (err ).ShouldNot (HaveOccurred ())
124+ result , err = parseResult (arg .StdinData )
125+ Expect (err ).ShouldNot (HaveOccurred ())
126+ address1 , _ := platform .ConvertStringToIPNet ("10.0.0.5/16" )
127+ address2 , _ := platform .ConvertStringToIPNet ("10.0.0.6/16" )
128+ Expect (result .IPs [0 ].Address .IP ).Should (Or (Equal (address1 .IP ), Equal (address2 .IP )))
129+ Expect (result .IPs [0 ].Address .Mask ).Should (Equal (address1 .Mask ))
130+ })
131+ })
132+
133+ Context ("When DELETE with subnet and address, call for ipam triggering release address" , func () {
134+ It ("DELETE address successfully" , func () {
135+ arg .StdinData = getStdinData ("0.4.0" , "10.0.0.0/16" , result .IPs [0 ].Address .IP .String ())
136+ err = plugin .Delete (arg )
137+ Expect (err ).ShouldNot (HaveOccurred ())
138+ })
139+ })
140+
141+ Context ("When DELETE with subnet, call for ipam triggering releasing pool" , func () {
142+ It ("DELETE pool successfully" , func () {
143+ arg .StdinData = getStdinData ("0.4.0" , "10.0.0.0/16" , "" )
144+ err = plugin .Delete (arg )
145+ Expect (err ).ShouldNot (HaveOccurred ())
146+ })
147+ })
148+ })
149+
150+ Describe ("Test IPAM ADD and DELETE address" , func () {
151+
152+ Context ("When address is given" , func () {
153+ It ("Request pool and address successfully" , func () {
154+ arg .StdinData = getStdinData ("0.4.0" , "" , "10.0.0.6" )
155+ err = plugin .Add (arg )
156+ Expect (err ).ShouldNot (HaveOccurred ())
157+ result , err := parseResult (arg .StdinData )
158+ Expect (err ).ShouldNot (HaveOccurred ())
159+ address , _ := platform .ConvertStringToIPNet ("10.0.0.6/16" )
160+ Expect (result .IPs [0 ].Address .IP ).Should (Equal (address .IP ))
161+ Expect (result .IPs [0 ].Address .Mask ).Should (Equal (address .Mask ))
162+ })
163+ })
164+
165+ Context ("When subnet is given" , func () {
166+ It ("Request a usable address successfully" , func () {
167+ arg .StdinData = getStdinData ("0.4.0" , "10.0.0.0/16" , "" )
168+ err = plugin .Add (arg )
169+ Expect (err ).ShouldNot (HaveOccurred ())
170+ result , err := parseResult (arg .StdinData )
171+ Expect (err ).ShouldNot (HaveOccurred ())
172+ address , _ := platform .ConvertStringToIPNet ("10.0.0.5/16" )
173+ Expect (result .IPs [0 ].Address .IP ).Should (Equal (address .IP ))
174+ Expect (result .IPs [0 ].Address .Mask ).Should (Equal (address .Mask ))
175+ })
176+ })
177+ })
178+
179+ Describe ("Test IPAM DELETE" , func () {
180+
181+ Context ("When address and subnet is given" , func () {
182+ It ("Release address successfully" , func () {
183+ arg .StdinData = getStdinData ("0.4.0" , "10.0.0.0/16" , "10.0.0.5" )
184+ err = plugin .Delete (arg )
185+ Expect (err ).ShouldNot (HaveOccurred ())
186+ })
187+ })
188+
189+ Context ("When address and subnet is given" , func () {
190+ It ("Release address successfully" , func () {
191+ arg .StdinData = getStdinData ("0.4.0" , "10.0.0.0/16" , "10.0.0.6" )
192+ err = plugin .Delete (arg )
193+ Expect (err ).ShouldNot (HaveOccurred ())
194+ })
195+ })
196+
197+ Context ("When subnet is given" , func () {
198+ It ("Release pool successfully" , func () {
199+ arg .StdinData = getStdinData ("0.4.0" , "10.0.0.0/16" , "" )
200+ err = plugin .Delete (arg )
201+ Expect (err ).ShouldNot (HaveOccurred ())
202+ })
203+ })
204+ })
205+ })
206+ )
0 commit comments