driver_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422
  1. package remote
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "net"
  6. "net/http"
  7. "os"
  8. "testing"
  9. "github.com/docker/docker/pkg/plugins"
  10. "github.com/docker/libnetwork/driverapi"
  11. _ "github.com/docker/libnetwork/netutils"
  12. "github.com/docker/libnetwork/types"
  13. )
  14. func decodeToMap(r *http.Request) (res map[string]interface{}, err error) {
  15. err = json.NewDecoder(r.Body).Decode(&res)
  16. return
  17. }
  18. func handle(t *testing.T, mux *http.ServeMux, method string, h func(map[string]interface{}) interface{}) {
  19. mux.HandleFunc(fmt.Sprintf("/%s.%s", driverapi.NetworkPluginEndpointType, method), func(w http.ResponseWriter, r *http.Request) {
  20. ask, err := decodeToMap(r)
  21. if err != nil {
  22. t.Fatal(err)
  23. }
  24. answer := h(ask)
  25. err = json.NewEncoder(w).Encode(&answer)
  26. if err != nil {
  27. t.Fatal(err)
  28. }
  29. })
  30. }
  31. func setupPlugin(t *testing.T, name string, mux *http.ServeMux) func() {
  32. if err := os.MkdirAll("/usr/share/docker/plugins", 0755); err != nil {
  33. t.Fatal(err)
  34. }
  35. listener, err := net.Listen("unix", fmt.Sprintf("/usr/share/docker/plugins/%s.sock", name))
  36. if err != nil {
  37. t.Fatal("Could not listen to the plugin socket")
  38. }
  39. mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
  40. fmt.Fprintf(w, `{"Implements": ["%s"]}`, driverapi.NetworkPluginEndpointType)
  41. })
  42. go http.Serve(listener, mux)
  43. return func() {
  44. listener.Close()
  45. if err := os.RemoveAll("/usr/share/docker/plugins"); err != nil {
  46. t.Fatal(err)
  47. }
  48. }
  49. }
  50. type testEndpoint struct {
  51. t *testing.T
  52. id int
  53. src string
  54. dst string
  55. address string
  56. addressIPv6 string
  57. macAddress string
  58. gateway string
  59. gatewayIPv6 string
  60. resolvConfPath string
  61. hostsPath string
  62. nextHop string
  63. destination string
  64. routeType int
  65. }
  66. func (test *testEndpoint) Interfaces() []driverapi.InterfaceInfo {
  67. // return an empty one so we don't trip the check for existing
  68. // interfaces; we don't care about this after that
  69. return []driverapi.InterfaceInfo{}
  70. }
  71. func (test *testEndpoint) AddInterface(ID int, mac net.HardwareAddr, ipv4 net.IPNet, ipv6 net.IPNet) error {
  72. if ID != test.id {
  73. test.t.Fatalf("Wrong ID passed to AddInterface: %d", ID)
  74. }
  75. ip4, net4, _ := net.ParseCIDR(test.address)
  76. ip6, net6, _ := net.ParseCIDR(test.addressIPv6)
  77. if ip4 != nil {
  78. net4.IP = ip4
  79. if !types.CompareIPNet(net4, &ipv4) {
  80. test.t.Fatalf("Wrong address given %+v", ipv4)
  81. }
  82. }
  83. if ip6 != nil {
  84. net6.IP = ip6
  85. if !types.CompareIPNet(net6, &ipv6) {
  86. test.t.Fatalf("Wrong address (IPv6) given %+v", ipv6)
  87. }
  88. }
  89. if test.macAddress != "" && mac.String() != test.macAddress {
  90. test.t.Fatalf("Wrong MAC address given %v", mac)
  91. }
  92. return nil
  93. }
  94. func (test *testEndpoint) InterfaceNames() []driverapi.InterfaceNameInfo {
  95. return []driverapi.InterfaceNameInfo{test}
  96. }
  97. func compareIPs(t *testing.T, kind string, shouldBe string, supplied net.IP) {
  98. ip := net.ParseIP(shouldBe)
  99. if ip == nil {
  100. t.Fatalf(`Invalid IP to test against: "%s"`, shouldBe)
  101. }
  102. if !ip.Equal(supplied) {
  103. t.Fatalf(`%s IPs are not equal: expected "%s", got %v`, kind, shouldBe, supplied)
  104. }
  105. }
  106. func compareIPNets(t *testing.T, kind string, shouldBe string, supplied net.IPNet) {
  107. _, net, _ := net.ParseCIDR(shouldBe)
  108. if net == nil {
  109. t.Fatalf(`Invalid IP network to test against: "%s"`, shouldBe)
  110. }
  111. if !types.CompareIPNet(net, &supplied) {
  112. t.Fatalf(`%s IP networks are not equal: expected "%s", got %v`, kind, shouldBe, supplied)
  113. }
  114. }
  115. func (test *testEndpoint) SetGateway(ipv4 net.IP) error {
  116. compareIPs(test.t, "Gateway", test.gateway, ipv4)
  117. return nil
  118. }
  119. func (test *testEndpoint) SetGatewayIPv6(ipv6 net.IP) error {
  120. compareIPs(test.t, "GatewayIPv6", test.gatewayIPv6, ipv6)
  121. return nil
  122. }
  123. func (test *testEndpoint) SetNames(src string, dst string) error {
  124. if test.src != src {
  125. test.t.Fatalf(`Wrong SrcName; expected "%s", got "%s"`, test.src, src)
  126. }
  127. if test.dst != dst {
  128. test.t.Fatalf(`Wrong DstPrefix; expected "%s", got "%s"`, test.dst, dst)
  129. }
  130. return nil
  131. }
  132. func (test *testEndpoint) AddStaticRoute(destination *net.IPNet, routeType int, nextHop net.IP, interfaceID int) error {
  133. compareIPNets(test.t, "Destination", test.destination, *destination)
  134. compareIPs(test.t, "NextHop", test.nextHop, nextHop)
  135. if test.routeType != routeType {
  136. test.t.Fatalf(`Wrong RouteType; expected "%d", got "%d"`, test.routeType, routeType)
  137. }
  138. if test.id != interfaceID {
  139. test.t.Fatalf(`Wrong InterfaceID; expected "%d", got "%d"`, test.id, interfaceID)
  140. }
  141. return nil
  142. }
  143. func (test *testEndpoint) ID() int {
  144. return test.id
  145. }
  146. func TestRemoteDriver(t *testing.T) {
  147. var plugin = "test-net-driver"
  148. ep := &testEndpoint{
  149. t: t,
  150. src: "vethsrc",
  151. dst: "vethdst",
  152. address: "192.168.5.7/16",
  153. addressIPv6: "2001:DB8::5:7/48",
  154. macAddress: "7a:56:78:34:12:da",
  155. gateway: "192.168.0.1",
  156. gatewayIPv6: "2001:DB8::1",
  157. hostsPath: "/here/comes/the/host/path",
  158. resolvConfPath: "/there/goes/the/resolv/conf",
  159. destination: "10.0.0.0/8",
  160. nextHop: "10.0.0.1",
  161. routeType: 1,
  162. }
  163. mux := http.NewServeMux()
  164. defer setupPlugin(t, plugin, mux)()
  165. var networkID string
  166. handle(t, mux, "CreateNetwork", func(msg map[string]interface{}) interface{} {
  167. nid := msg["NetworkID"]
  168. var ok bool
  169. if networkID, ok = nid.(string); !ok {
  170. t.Fatal("RPC did not include network ID string")
  171. }
  172. return map[string]interface{}{}
  173. })
  174. handle(t, mux, "DeleteNetwork", func(msg map[string]interface{}) interface{} {
  175. if nid, ok := msg["NetworkID"]; !ok || nid != networkID {
  176. t.Fatal("Network ID missing or does not match that created")
  177. }
  178. return map[string]interface{}{}
  179. })
  180. handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
  181. iface := map[string]interface{}{
  182. "ID": ep.id,
  183. "Address": ep.address,
  184. "AddressIPv6": ep.addressIPv6,
  185. "MacAddress": ep.macAddress,
  186. }
  187. return map[string]interface{}{
  188. "Interfaces": []interface{}{iface},
  189. }
  190. })
  191. handle(t, mux, "Join", func(msg map[string]interface{}) interface{} {
  192. options := msg["Options"].(map[string]interface{})
  193. foo, ok := options["foo"].(string)
  194. if !ok || foo != "fooValue" {
  195. t.Fatalf("Did not receive expected foo string in request options: %+v", msg)
  196. }
  197. return map[string]interface{}{
  198. "Gateway": ep.gateway,
  199. "GatewayIPv6": ep.gatewayIPv6,
  200. "HostsPath": ep.hostsPath,
  201. "ResolvConfPath": ep.resolvConfPath,
  202. "InterfaceNames": []map[string]interface{}{
  203. map[string]interface{}{
  204. "SrcName": ep.src,
  205. "DstPrefix": ep.dst,
  206. },
  207. },
  208. "StaticRoutes": []map[string]interface{}{
  209. map[string]interface{}{
  210. "Destination": ep.destination,
  211. "RouteType": ep.routeType,
  212. "InterfaceID": ep.id,
  213. "NextHop": ep.nextHop,
  214. },
  215. },
  216. }
  217. })
  218. handle(t, mux, "Leave", func(msg map[string]interface{}) interface{} {
  219. return map[string]string{}
  220. })
  221. handle(t, mux, "DeleteEndpoint", func(msg map[string]interface{}) interface{} {
  222. return map[string]interface{}{}
  223. })
  224. handle(t, mux, "EndpointOperInfo", func(msg map[string]interface{}) interface{} {
  225. return map[string]interface{}{
  226. "Value": map[string]string{
  227. "Arbitrary": "key",
  228. "Value": "pairs?",
  229. },
  230. }
  231. })
  232. p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
  233. if err != nil {
  234. t.Fatal(err)
  235. }
  236. driver := newDriver(plugin, p.Client)
  237. if driver.Type() != plugin {
  238. t.Fatal("Driver type does not match that given")
  239. }
  240. netID := "dummy-network"
  241. err = driver.CreateNetwork(netID, map[string]interface{}{})
  242. if err != nil {
  243. t.Fatal(err)
  244. }
  245. endID := "dummy-endpoint"
  246. err = driver.CreateEndpoint(netID, endID, ep, map[string]interface{}{})
  247. if err != nil {
  248. t.Fatal(err)
  249. }
  250. joinOpts := map[string]interface{}{"foo": "fooValue"}
  251. err = driver.Join(netID, endID, "sandbox-key", ep, joinOpts)
  252. if err != nil {
  253. t.Fatal(err)
  254. }
  255. if _, err = driver.EndpointOperInfo(netID, endID); err != nil {
  256. t.Fatal(err)
  257. }
  258. if err = driver.Leave(netID, endID); err != nil {
  259. t.Fatal(err)
  260. }
  261. if err = driver.DeleteEndpoint(netID, endID); err != nil {
  262. t.Fatal(err)
  263. }
  264. if err = driver.DeleteNetwork(netID); err != nil {
  265. t.Fatal(err)
  266. }
  267. }
  268. type failEndpoint struct {
  269. t *testing.T
  270. }
  271. func (f *failEndpoint) Interfaces() []*driverapi.InterfaceInfo {
  272. f.t.Fatal("Unexpected call of Interfaces")
  273. return nil
  274. }
  275. func (f *failEndpoint) AddInterface(int, net.HardwareAddr, net.IPNet, net.IPNet) error {
  276. f.t.Fatal("Unexpected call of AddInterface")
  277. return nil
  278. }
  279. func TestDriverError(t *testing.T) {
  280. var plugin = "test-net-driver-error"
  281. mux := http.NewServeMux()
  282. defer setupPlugin(t, plugin, mux)()
  283. handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
  284. return map[string]interface{}{
  285. "Err": "this should get raised as an error",
  286. }
  287. })
  288. p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
  289. if err != nil {
  290. t.Fatal(err)
  291. }
  292. driver := newDriver(plugin, p.Client)
  293. if err := driver.CreateEndpoint("dummy", "dummy", &testEndpoint{t: t}, map[string]interface{}{}); err == nil {
  294. t.Fatalf("Expected error from driver")
  295. }
  296. }
  297. func TestMissingValues(t *testing.T) {
  298. var plugin = "test-net-driver-missing"
  299. mux := http.NewServeMux()
  300. defer setupPlugin(t, plugin, mux)()
  301. ep := &testEndpoint{
  302. t: t,
  303. id: 0,
  304. }
  305. handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
  306. iface := map[string]interface{}{
  307. "ID": ep.id,
  308. "Address": ep.address,
  309. "AddressIPv6": ep.addressIPv6,
  310. "MacAddress": ep.macAddress,
  311. }
  312. return map[string]interface{}{
  313. "Interfaces": []interface{}{iface},
  314. }
  315. })
  316. p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
  317. if err != nil {
  318. t.Fatal(err)
  319. }
  320. driver := newDriver(plugin, p.Client)
  321. if err := driver.CreateEndpoint("dummy", "dummy", ep, map[string]interface{}{}); err != nil {
  322. t.Fatal(err)
  323. }
  324. }
  325. type rollbackEndpoint struct {
  326. }
  327. func (r *rollbackEndpoint) Interfaces() []driverapi.InterfaceInfo {
  328. return []driverapi.InterfaceInfo{}
  329. }
  330. func (r *rollbackEndpoint) AddInterface(_ int, _ net.HardwareAddr, _ net.IPNet, _ net.IPNet) error {
  331. return fmt.Errorf("fail this to trigger a rollback")
  332. }
  333. func TestRollback(t *testing.T) {
  334. var plugin = "test-net-driver-rollback"
  335. mux := http.NewServeMux()
  336. defer setupPlugin(t, plugin, mux)()
  337. rolledback := false
  338. handle(t, mux, "CreateEndpoint", func(msg map[string]interface{}) interface{} {
  339. iface := map[string]interface{}{
  340. "ID": 0,
  341. "Address": "192.168.4.5/16",
  342. "AddressIPv6": "",
  343. "MacAddress": "7a:12:34:56:78:90",
  344. }
  345. return map[string]interface{}{
  346. "Interfaces": []interface{}{iface},
  347. }
  348. })
  349. handle(t, mux, "DeleteEndpoint", func(msg map[string]interface{}) interface{} {
  350. rolledback = true
  351. return map[string]interface{}{}
  352. })
  353. p, err := plugins.Get(plugin, driverapi.NetworkPluginEndpointType)
  354. if err != nil {
  355. t.Fatal(err)
  356. }
  357. driver := newDriver(plugin, p.Client)
  358. ep := &rollbackEndpoint{}
  359. if err := driver.CreateEndpoint("dummy", "dummy", ep, map[string]interface{}{}); err == nil {
  360. t.Fatalf("Expected error from driver")
  361. }
  362. if !rolledback {
  363. t.Fatalf("Expected to have had DeleteEndpoint called")
  364. }
  365. }