driver_test.go 13 KB

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