netsh_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  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 netsh
  14. import (
  15. "net"
  16. "os"
  17. "testing"
  18. "k8s.io/utils/exec"
  19. fakeexec "k8s.io/utils/exec/testing"
  20. "github.com/pkg/errors"
  21. "github.com/stretchr/testify/assert"
  22. )
  23. func fakeCommonRunner() *runner {
  24. fakeCmd := fakeexec.FakeCmd{
  25. CombinedOutputScript: []fakeexec.FakeAction{
  26. // Success
  27. func() ([]byte, []byte, error) {
  28. return []byte{}, nil, nil
  29. },
  30. // utilexec.ExitError exists, and status is not 0
  31. func() ([]byte, []byte, error) {
  32. return nil, nil, &fakeexec.FakeExitError{Status: 1}
  33. },
  34. // utilexec.ExitError exists, and status is 0
  35. func() ([]byte, []byte, error) {
  36. return nil, nil, &fakeexec.FakeExitError{Status: 0}
  37. },
  38. // other error exists
  39. func() ([]byte, []byte, error) {
  40. return nil, nil, errors.New("not ExitError")
  41. },
  42. },
  43. }
  44. return &runner{
  45. exec: &fakeexec.FakeExec{
  46. CommandScript: []fakeexec.FakeCommandAction{
  47. func(cmd string, args ...string) exec.Cmd {
  48. return fakeexec.InitFakeCmd(&fakeCmd, cmd, args...)
  49. },
  50. func(cmd string, args ...string) exec.Cmd {
  51. return fakeexec.InitFakeCmd(&fakeCmd, cmd, args...)
  52. },
  53. func(cmd string, args ...string) exec.Cmd {
  54. return fakeexec.InitFakeCmd(&fakeCmd, cmd, args...)
  55. },
  56. func(cmd string, args ...string) exec.Cmd {
  57. return fakeexec.InitFakeCmd(&fakeCmd, cmd, args...)
  58. },
  59. },
  60. },
  61. }
  62. }
  63. func TestEnsurePortProxyRule(t *testing.T) {
  64. runner := fakeCommonRunner()
  65. tests := []struct {
  66. name string
  67. arguments []string
  68. expectedResult bool
  69. expectedError bool
  70. }{
  71. {"Success", []string{"ensure-port-proxy-rule"}, true, false},
  72. {"utilexec.ExitError exists, and status is not 0", []string{"ensure-port-proxy-rule"}, false, false},
  73. {"utilexec.ExitError exists, and status is 0", []string{"ensure-port-proxy-rule"}, false, true},
  74. {"other error exists", []string{"ensure-port-proxy-rule"}, false, true},
  75. }
  76. for _, test := range tests {
  77. result, err := runner.EnsurePortProxyRule(test.arguments)
  78. if test.expectedError {
  79. assert.Errorf(t, err, "Failed to test: %s", test.name)
  80. } else {
  81. if err != nil {
  82. assert.NoErrorf(t, err, "Failed to test: %s", test.name)
  83. } else {
  84. assert.EqualValuesf(t, test.expectedResult, result, "Failed to test: %s", test.name)
  85. }
  86. }
  87. }
  88. }
  89. func TestDeletePortProxyRule(t *testing.T) {
  90. runner := fakeCommonRunner()
  91. tests := []struct {
  92. name string
  93. arguments []string
  94. expectedError bool
  95. }{
  96. {"Success", []string{"delete-port-proxy-rule"}, false},
  97. {"utilexec.ExitError exists, and status is not 0", []string{"delete-port-proxy-rule"}, true},
  98. {"utilexec.ExitError exists, and status is 0", []string{"delete-port-proxy-rule"}, false},
  99. {"other error exists", []string{"delete-port-proxy-rule"}, true},
  100. }
  101. for _, test := range tests {
  102. err := runner.DeletePortProxyRule(test.arguments)
  103. if test.expectedError {
  104. assert.Errorf(t, err, "Failed to test: %s", test.name)
  105. } else {
  106. assert.NoErrorf(t, err, "Failed to test: %s", test.name)
  107. }
  108. }
  109. }
  110. func TestEnsureIPAddress(t *testing.T) {
  111. tests := []struct {
  112. name string
  113. arguments []string
  114. ip net.IP
  115. fakeCmdAction []fakeexec.FakeCommandAction
  116. expectedError bool
  117. expectedResult bool
  118. }{
  119. {
  120. "IP address exists",
  121. []string{"delete-port-proxy-rule"},
  122. net.IPv4(10, 10, 10, 20),
  123. []fakeexec.FakeCommandAction{
  124. func(cmd string, args ...string) exec.Cmd {
  125. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  126. CombinedOutputScript: []fakeexec.FakeAction{
  127. // IP address exists
  128. func() ([]byte, []byte, error) {
  129. return []byte("IP Address:10.10.10.10\nIP Address:10.10.10.20"), nil, nil
  130. },
  131. },
  132. }, cmd, args...)
  133. },
  134. },
  135. false,
  136. true,
  137. },
  138. {
  139. "IP address not exists, but set successful(find it in the second time)",
  140. []string{"ensure-ip-address"},
  141. net.IPv4(10, 10, 10, 20),
  142. []fakeexec.FakeCommandAction{
  143. func(cmd string, args ...string) exec.Cmd {
  144. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  145. CombinedOutputScript: []fakeexec.FakeAction{
  146. // IP address not exists
  147. func() ([]byte, []byte, error) {
  148. return []byte("IP Address:10.10.10.10"), nil, nil
  149. },
  150. },
  151. }, cmd, args...)
  152. },
  153. func(cmd string, args ...string) exec.Cmd {
  154. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  155. CombinedOutputScript: []fakeexec.FakeAction{
  156. // Success to set ip
  157. func() ([]byte, []byte, error) {
  158. return []byte(""), nil, nil
  159. },
  160. },
  161. }, cmd, args...)
  162. },
  163. func(cmd string, args ...string) exec.Cmd {
  164. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  165. CombinedOutputScript: []fakeexec.FakeAction{
  166. // IP address still not exists
  167. func() ([]byte, []byte, error) {
  168. return []byte("IP Address:10.10.10.10"), nil, nil
  169. },
  170. },
  171. }, cmd, args...)
  172. },
  173. func(cmd string, args ...string) exec.Cmd {
  174. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  175. CombinedOutputScript: []fakeexec.FakeAction{
  176. // IP address exists
  177. func() ([]byte, []byte, error) {
  178. return []byte("IP Address:10.10.10.10\nIP Address:10.10.10.20"), nil, nil
  179. },
  180. },
  181. }, cmd, args...)
  182. },
  183. },
  184. false,
  185. true,
  186. },
  187. {
  188. "IP address not exists, utilexec.ExitError exists, but status is not 0)",
  189. []string{"ensure-ip-address"},
  190. net.IPv4(10, 10, 10, 20),
  191. []fakeexec.FakeCommandAction{
  192. func(cmd string, args ...string) exec.Cmd {
  193. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  194. CombinedOutputScript: []fakeexec.FakeAction{
  195. // IP address not exists
  196. func() ([]byte, []byte, error) {
  197. return []byte("IP Address:10.10.10.10"), nil, nil
  198. },
  199. },
  200. }, cmd, args...)
  201. },
  202. func(cmd string, args ...string) exec.Cmd {
  203. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  204. CombinedOutputScript: []fakeexec.FakeAction{
  205. // Failed to set ip, utilexec.ExitError exists, and status is not 0
  206. func() ([]byte, []byte, error) {
  207. return nil, nil, &fakeexec.FakeExitError{Status: 1}
  208. },
  209. },
  210. }, cmd, args...)
  211. },
  212. },
  213. false,
  214. false,
  215. },
  216. {
  217. "IP address not exists, utilexec.ExitError exists, and status is 0)",
  218. []string{"ensure-ip-address"},
  219. net.IPv4(10, 10, 10, 20),
  220. []fakeexec.FakeCommandAction{
  221. func(cmd string, args ...string) exec.Cmd {
  222. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  223. CombinedOutputScript: []fakeexec.FakeAction{
  224. // IP address not exists
  225. func() ([]byte, []byte, error) {
  226. return []byte("IP Address:10.10.10.10"), nil, nil
  227. },
  228. },
  229. }, cmd, args...)
  230. },
  231. func(cmd string, args ...string) exec.Cmd {
  232. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  233. CombinedOutputScript: []fakeexec.FakeAction{
  234. // Failed to set ip, utilexec.ExitError exists, and status is 0
  235. func() ([]byte, []byte, error) {
  236. return nil, nil, &fakeexec.FakeExitError{Status: 0}
  237. },
  238. },
  239. }, cmd, args...)
  240. },
  241. },
  242. true,
  243. false,
  244. },
  245. {
  246. "IP address not exists, and error is not utilexec.ExitError)",
  247. []string{"ensure-ip-address"},
  248. net.IPv4(10, 10, 10, 20),
  249. []fakeexec.FakeCommandAction{
  250. func(cmd string, args ...string) exec.Cmd {
  251. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  252. CombinedOutputScript: []fakeexec.FakeAction{
  253. // IP address not exists
  254. func() ([]byte, []byte, error) {
  255. return []byte("IP Address:10.10.10.10"), nil, nil
  256. },
  257. },
  258. }, cmd, args...)
  259. },
  260. func(cmd string, args ...string) exec.Cmd {
  261. return fakeexec.InitFakeCmd(&fakeexec.FakeCmd{
  262. CombinedOutputScript: []fakeexec.FakeAction{
  263. // Failed to set ip, other error exists
  264. func() ([]byte, []byte, error) {
  265. return nil, nil, errors.New("not ExitError")
  266. },
  267. },
  268. }, cmd, args...)
  269. },
  270. },
  271. true,
  272. false,
  273. },
  274. }
  275. for _, test := range tests {
  276. runner := New(&fakeexec.FakeExec{CommandScript: test.fakeCmdAction})
  277. result, err := runner.EnsureIPAddress(test.arguments, test.ip)
  278. if test.expectedError {
  279. assert.Errorf(t, err, "Failed to test: %s", test.name)
  280. } else {
  281. if err != nil {
  282. assert.NoErrorf(t, err, "Failed to test: %s", test.name)
  283. } else {
  284. assert.EqualValuesf(t, test.expectedResult, result, "Failed to test: %s", test.name)
  285. }
  286. }
  287. }
  288. }
  289. func TestDeleteIPAddress(t *testing.T) {
  290. runner := fakeCommonRunner()
  291. tests := []struct {
  292. name string
  293. arguments []string
  294. expectedError bool
  295. }{
  296. {"Success", []string{"delete-ip-address"}, false},
  297. {"utilexec.ExitError exists, and status is not 0", []string{"delete-ip-address"}, true},
  298. {"utilexec.ExitError exists, and status is 0", []string{"delete-ip-address"}, false},
  299. {"other error exists", []string{"delete-ip-address"}, true},
  300. }
  301. for _, test := range tests {
  302. err := runner.DeleteIPAddress(test.arguments)
  303. if test.expectedError {
  304. assert.Errorf(t, err, "Failed to test: %s", test.name)
  305. } else {
  306. assert.NoErrorf(t, err, "Failed to test: %s", test.name)
  307. }
  308. }
  309. }
  310. func TestGetInterfaceToAddIP(t *testing.T) {
  311. // backup env 'INTERFACE_TO_ADD_SERVICE_IP'
  312. backupValue := os.Getenv("INTERFACE_TO_ADD_SERVICE_IP")
  313. // recover env
  314. defer os.Setenv("INTERFACE_TO_ADD_SERVICE_IP", backupValue)
  315. tests := []struct {
  316. name string
  317. envToBeSet string
  318. expectedResult string
  319. }{
  320. {"env_value_is_empty", "", "vEthernet (HNS Internal NIC)"},
  321. {"env_value_is_not_empty", "eth0", "eth0"},
  322. }
  323. fakeExec := fakeexec.FakeExec{
  324. CommandScript: []fakeexec.FakeCommandAction{},
  325. }
  326. netsh := New(&fakeExec)
  327. for _, test := range tests {
  328. os.Setenv("INTERFACE_TO_ADD_SERVICE_IP", test.envToBeSet)
  329. result := netsh.GetInterfaceToAddIP()
  330. assert.EqualValuesf(t, test.expectedResult, result, "Failed to test: %s", test.name)
  331. }
  332. }
  333. func TestRestore(t *testing.T) {
  334. runner := New(&fakeexec.FakeExec{
  335. CommandScript: []fakeexec.FakeCommandAction{},
  336. })
  337. result := runner.Restore([]string{})
  338. assert.NoErrorf(t, result, "The return value must be nil")
  339. }
  340. func TestCheckIPExists(t *testing.T) {
  341. fakeCmd := fakeexec.FakeCmd{
  342. CombinedOutputScript: []fakeexec.FakeAction{
  343. // Error exists
  344. func() ([]byte, []byte, error) {
  345. return nil, nil, &fakeexec.FakeExitError{Status: 1}
  346. },
  347. // IP address string is empty
  348. func() ([]byte, []byte, error) {
  349. return []byte(""), nil, nil
  350. },
  351. // "IP Address:" field not exists
  352. func() ([]byte, []byte, error) {
  353. return []byte("10.10.10.10"), nil, nil
  354. },
  355. // IP not exists
  356. func() ([]byte, []byte, error) {
  357. return []byte("IP Address:10.10.10.10"), nil, nil
  358. },
  359. // IP exists
  360. func() ([]byte, []byte, error) {
  361. return []byte("IP Address:10.10.10.10\nIP Address:10.10.10.20"), nil, nil
  362. },
  363. },
  364. }
  365. fakeExec := fakeexec.FakeExec{
  366. CommandScript: []fakeexec.FakeCommandAction{
  367. func(cmd string, args ...string) exec.Cmd {
  368. return fakeexec.InitFakeCmd(&fakeCmd, cmd, args...)
  369. },
  370. func(cmd string, args ...string) exec.Cmd {
  371. return fakeexec.InitFakeCmd(&fakeCmd, cmd, args...)
  372. },
  373. func(cmd string, args ...string) exec.Cmd {
  374. return fakeexec.InitFakeCmd(&fakeCmd, cmd, args...)
  375. },
  376. func(cmd string, args ...string) exec.Cmd {
  377. return fakeexec.InitFakeCmd(&fakeCmd, cmd, args...)
  378. },
  379. func(cmd string, args ...string) exec.Cmd {
  380. return fakeexec.InitFakeCmd(&fakeCmd, cmd, args...)
  381. },
  382. },
  383. }
  384. fakeRunner := &runner{
  385. exec: &fakeExec,
  386. }
  387. tests := []struct {
  388. name string
  389. ipToCheck string
  390. arguments []string
  391. expectedError bool
  392. expectedResult bool
  393. }{
  394. {"Error exists", "10.10.10.20", []string{"check-IP-exists"}, true, false},
  395. {"IP address string is empty", "10.10.10.20", []string{"check-IP-exists"}, false, false},
  396. {"'IP Address:' field not exists", "10.10.10.20", []string{"check-IP-exists"}, false, false},
  397. {"IP not exists", "10.10.10.20", []string{"check-IP-exists"}, false, false},
  398. {"IP exists", "10.10.10.20", []string{"check-IP-exists"}, false, true},
  399. }
  400. for _, test := range tests {
  401. result, err := checkIPExists(test.ipToCheck, test.arguments, fakeRunner)
  402. if test.expectedError {
  403. assert.Errorf(t, err, "Failed to test: %s", test.name)
  404. } else {
  405. assert.EqualValuesf(t, test.expectedResult, result, "Failed to test: %s", test.name)
  406. }
  407. }
  408. }
  409. func TestGetIP(t *testing.T) {
  410. testcases := []struct {
  411. showAddress string
  412. expectAddress string
  413. }{
  414. {
  415. showAddress: "IP 地址: 10.96.0.2",
  416. expectAddress: "10.96.0.2",
  417. },
  418. {
  419. showAddress: "IP Address: 10.96.0.3",
  420. expectAddress: "10.96.0.3",
  421. },
  422. {
  423. showAddress: "IP Address:10.96.0.4",
  424. expectAddress: "10.96.0.4",
  425. },
  426. }
  427. for _, tc := range testcases {
  428. address := getIP(tc.showAddress)
  429. if address != tc.expectAddress {
  430. t.Errorf("expected address=%q, got %q", tc.expectAddress, address)
  431. }
  432. }
  433. }