PageRenderTime 45ms CodeModel.GetById 10ms RepoModel.GetById 1ms app.codeStats 0ms

/pkg/util/net/interface_test.go

https://gitlab.com/hasura/kubernetes
Go | 300 lines | 258 code | 26 blank | 16 comment | 18 complexity | 9b64380e1ec8bd4a0ca5b13251619706 MD5 | raw file
  1. /*
  2. Copyright 2014 The Kubernetes Authors All rights reserved.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package net
  14. import (
  15. "fmt"
  16. "io"
  17. "net"
  18. "strings"
  19. "testing"
  20. )
  21. const gatewayfirst = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
  22. eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
  23. eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
  24. docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
  25. virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
  26. `
  27. const gatewaylast = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
  28. docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
  29. virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
  30. eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
  31. eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
  32. `
  33. const gatewaymiddle = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
  34. eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
  35. docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
  36. eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
  37. virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
  38. `
  39. const noInternetConnection = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
  40. docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
  41. virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
  42. `
  43. const nothing = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
  44. `
  45. const gatewayfirstIpv6_1 = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
  46. eth3 00000000 0100FE0A 0003 0 0 1024 00000000 0 0 0
  47. eth3 0000FE0AA1 00000000 0001 0 0 0 0080FFFF 0 0 0
  48. docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
  49. virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
  50. `
  51. const gatewayfirstIpv6_2 = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
  52. eth3 00000000 0100FE0AA1 0003 0 0 1024 00000000 0 0 0
  53. eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
  54. docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
  55. virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
  56. `
  57. const route_Invalidhex = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
  58. eth3 00000000 0100FE0AA 0003 0 0 1024 00000000 0 0 0
  59. eth3 0000FE0A 00000000 0001 0 0 0 0080FFFF 0 0 0
  60. docker0 000011AC 00000000 0001 0 0 0 0000FFFF 0 0 0
  61. virbr0 007AA8C0 00000000 0001 0 0 0 00FFFFFF 0 0 0
  62. `
  63. // Based on DigitalOcean COREOS
  64. const gatewayfirstLinkLocal = `Iface Destination Gateway Flags RefCnt Use Metric Mask MTU Window IRTT
  65. eth0 00000000 0120372D 0001 0 0 0 00000000 0 0 0
  66. eth0 00000000 00000000 0001 0 0 2048 00000000 0 0 0
  67. `
  68. func TestGetRoutes(t *testing.T) {
  69. testCases := []struct {
  70. tcase string
  71. route string
  72. expected int
  73. }{
  74. {"gatewayfirst", gatewayfirst, 4},
  75. {"gatewaymiddle", gatewaymiddle, 4},
  76. {"gatewaylast", gatewaylast, 4},
  77. {"nothing", nothing, 0},
  78. {"gatewayfirstIpv6_1", gatewayfirstIpv6_1, 0},
  79. {"gatewayfirstIpv6_2", gatewayfirstIpv6_2, 0},
  80. {"route_Invalidhex", route_Invalidhex, 0},
  81. }
  82. for _, tc := range testCases {
  83. r := strings.NewReader(tc.route)
  84. routes, err := getRoutes(r)
  85. if len(routes) != tc.expected {
  86. t.Errorf("case[%v]: expected %v, got %v .err : %v", tc.tcase, tc.expected, len(routes), err)
  87. }
  88. }
  89. }
  90. func TestParseIP(t *testing.T) {
  91. testCases := []struct {
  92. tcase string
  93. ip string
  94. success bool
  95. expected net.IP
  96. }{
  97. {"empty", "", false, nil},
  98. {"too short", "AA", false, nil},
  99. {"too long", "0011223344", false, nil},
  100. {"invalid", "invalid!", false, nil},
  101. {"zero", "00000000", true, net.IP{0, 0, 0, 0}},
  102. {"ffff", "FFFFFFFF", true, net.IP{0xff, 0xff, 0xff, 0xff}},
  103. {"valid", "12345678", true, net.IP{120, 86, 52, 18}},
  104. }
  105. for _, tc := range testCases {
  106. ip, err := parseIP(tc.ip)
  107. if !ip.Equal(tc.expected) {
  108. t.Errorf("case[%v]: expected %q, got %q . err : %v", tc.tcase, tc.expected, ip, err)
  109. }
  110. }
  111. }
  112. func TestIsInterfaceUp(t *testing.T) {
  113. testCases := []struct {
  114. tcase string
  115. intf net.Interface
  116. expected bool
  117. }{
  118. {"up", net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}, true},
  119. {"down", net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: 0}, false},
  120. {"nothing", net.Interface{}, false},
  121. }
  122. for _, tc := range testCases {
  123. it := isInterfaceUp(&tc.intf)
  124. if it != tc.expected {
  125. t.Errorf("case[%v]: expected %v, got %v .", tc.tcase, tc.expected, it)
  126. }
  127. }
  128. }
  129. type addrStruct struct{ val string }
  130. func (a addrStruct) Network() string {
  131. return a.val
  132. }
  133. func (a addrStruct) String() string {
  134. return a.val
  135. }
  136. func TestFinalIP(t *testing.T) {
  137. testCases := []struct {
  138. tcase string
  139. addr []net.Addr
  140. expected net.IP
  141. }{
  142. {"ipv6", []net.Addr{addrStruct{val: "fe80::2f7:6fff:fe6e:2956/64"}}, nil},
  143. {"invalidCIDR", []net.Addr{addrStruct{val: "fe80::2f7:67fff:fe6e:2956/64"}}, nil},
  144. {"loopback", []net.Addr{addrStruct{val: "127.0.0.1/24"}}, nil},
  145. {"ip4", []net.Addr{addrStruct{val: "10.254.12.132/17"}}, net.ParseIP("10.254.12.132")},
  146. {"nothing", []net.Addr{}, nil},
  147. }
  148. for _, tc := range testCases {
  149. ip, err := getFinalIP(tc.addr)
  150. if !ip.Equal(tc.expected) {
  151. t.Errorf("case[%v]: expected %v, got %v .err : %v", tc.tcase, tc.expected, ip, err)
  152. }
  153. }
  154. }
  155. func TestAddrs(t *testing.T) {
  156. var nw networkInterfacer = validNetworkInterface{}
  157. intf := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: 0}
  158. addrs, err := nw.Addrs(&intf)
  159. if err != nil {
  160. t.Errorf("expected no error got : %v", err)
  161. }
  162. if len(addrs) != 2 {
  163. t.Errorf("expected addrs: 2 got null")
  164. }
  165. }
  166. type validNetworkInterface struct {
  167. }
  168. func (_ validNetworkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
  169. c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
  170. return &c, nil
  171. }
  172. func (_ validNetworkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
  173. var ifat []net.Addr
  174. ifat = []net.Addr{
  175. addrStruct{val: "fe80::2f7:6fff:fe6e:2956/64"}, addrStruct{val: "10.254.71.145/17"}}
  176. return ifat, nil
  177. }
  178. type validNetworkInterfaceWithLinkLocal struct {
  179. }
  180. func (_ validNetworkInterfaceWithLinkLocal) InterfaceByName(intfName string) (*net.Interface, error) {
  181. c := net.Interface{Index: 0, MTU: 0, Name: "eth0", HardwareAddr: nil, Flags: net.FlagUp}
  182. return &c, nil
  183. }
  184. func (_ validNetworkInterfaceWithLinkLocal) Addrs(intf *net.Interface) ([]net.Addr, error) {
  185. var ifat []net.Addr
  186. ifat = []net.Addr{addrStruct{val: "169.254.162.166/16"}, addrStruct{val: "45.55.47.146/19"}}
  187. return ifat, nil
  188. }
  189. type validNetworkInterfacewithIpv6Only struct {
  190. }
  191. func (_ validNetworkInterfacewithIpv6Only) InterfaceByName(intfName string) (*net.Interface, error) {
  192. c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
  193. return &c, nil
  194. }
  195. func (_ validNetworkInterfacewithIpv6Only) Addrs(intf *net.Interface) ([]net.Addr, error) {
  196. var ifat []net.Addr
  197. ifat = []net.Addr{addrStruct{val: "fe80::2f7:6fff:fe6e:2956/64"}}
  198. return ifat, nil
  199. }
  200. type noNetworkInterface struct {
  201. }
  202. func (_ noNetworkInterface) InterfaceByName(intfName string) (*net.Interface, error) {
  203. return nil, fmt.Errorf("unable get Interface")
  204. }
  205. func (_ noNetworkInterface) Addrs(intf *net.Interface) ([]net.Addr, error) {
  206. return nil, nil
  207. }
  208. type networkInterfacewithNoAddrs struct {
  209. }
  210. func (_ networkInterfacewithNoAddrs) InterfaceByName(intfName string) (*net.Interface, error) {
  211. c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
  212. return &c, nil
  213. }
  214. func (_ networkInterfacewithNoAddrs) Addrs(intf *net.Interface) ([]net.Addr, error) {
  215. return nil, fmt.Errorf("unable get Addrs")
  216. }
  217. type networkInterfacewithIpv6addrs struct {
  218. }
  219. func (_ networkInterfacewithIpv6addrs) InterfaceByName(intfName string) (*net.Interface, error) {
  220. c := net.Interface{Index: 0, MTU: 0, Name: "eth3", HardwareAddr: nil, Flags: net.FlagUp}
  221. return &c, nil
  222. }
  223. func (_ networkInterfacewithIpv6addrs) Addrs(intf *net.Interface) ([]net.Addr, error) {
  224. var ifat []net.Addr
  225. ifat = []net.Addr{addrStruct{val: "fe80::2f7:6ffff:fe6e:2956/64"}}
  226. return ifat, nil
  227. }
  228. func TestGetIPFromInterface(t *testing.T) {
  229. testCases := []struct {
  230. tcase string
  231. nwname string
  232. nw networkInterfacer
  233. expected net.IP
  234. }{
  235. {"valid", "eth3", validNetworkInterface{}, net.ParseIP("10.254.71.145")},
  236. {"ipv6", "eth3", validNetworkInterfacewithIpv6Only{}, nil},
  237. {"nothing", "eth3", noNetworkInterface{}, nil},
  238. }
  239. for _, tc := range testCases {
  240. ip, err := getIPFromInterface(tc.nwname, tc.nw)
  241. if !ip.Equal(tc.expected) {
  242. t.Errorf("case[%v]: expected %v, got %+v .err : %v", tc.tcase, tc.expected, ip, err)
  243. }
  244. }
  245. }
  246. func TestChooseHostInterfaceFromRoute(t *testing.T) {
  247. testCases := []struct {
  248. tcase string
  249. inFile io.Reader
  250. nw networkInterfacer
  251. expected net.IP
  252. }{
  253. {"valid_routefirst", strings.NewReader(gatewayfirst), validNetworkInterface{}, net.ParseIP("10.254.71.145")},
  254. {"valid_routelast", strings.NewReader(gatewaylast), validNetworkInterface{}, net.ParseIP("10.254.71.145")},
  255. {"valid_routemiddle", strings.NewReader(gatewaymiddle), validNetworkInterface{}, net.ParseIP("10.254.71.145")},
  256. {"valid_routemiddle_ipv6", strings.NewReader(gatewaymiddle), validNetworkInterfacewithIpv6Only{}, nil},
  257. {"no internet connection", strings.NewReader(noInternetConnection), validNetworkInterface{}, nil},
  258. {"no non-link-local ip", strings.NewReader(gatewayfirstLinkLocal), validNetworkInterfaceWithLinkLocal{}, net.ParseIP("45.55.47.146")},
  259. {"no route", strings.NewReader(nothing), validNetworkInterface{}, nil},
  260. {"no route file", nil, validNetworkInterface{}, nil},
  261. {"no interfaces", nil, noNetworkInterface{}, nil},
  262. {"no interface Addrs", strings.NewReader(gatewaymiddle), networkInterfacewithNoAddrs{}, nil},
  263. {"Invalid Addrs", strings.NewReader(gatewaymiddle), networkInterfacewithIpv6addrs{}, nil},
  264. }
  265. for _, tc := range testCases {
  266. ip, err := chooseHostInterfaceFromRoute(tc.inFile, tc.nw)
  267. if !ip.Equal(tc.expected) {
  268. t.Errorf("case[%v]: expected %v, got %+v .err : %v", tc.tcase, tc.expected, ip, err)
  269. }
  270. }
  271. }