controller_test.go 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867
  1. /*
  2. Copyright 2014 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 master
  14. import (
  15. "errors"
  16. "net"
  17. "reflect"
  18. "testing"
  19. "k8s.io/kubernetes/pkg/api"
  20. "k8s.io/kubernetes/pkg/registry/registrytest"
  21. "k8s.io/kubernetes/pkg/util/intstr"
  22. )
  23. func TestReconcileEndpoints(t *testing.T) {
  24. ns := api.NamespaceDefault
  25. om := func(name string) api.ObjectMeta {
  26. return api.ObjectMeta{Namespace: ns, Name: name}
  27. }
  28. reconcile_tests := []struct {
  29. testName string
  30. serviceName string
  31. ip string
  32. endpointPorts []api.EndpointPort
  33. additionalMasters int
  34. endpoints *api.EndpointsList
  35. expectUpdate *api.Endpoints // nil means none expected
  36. }{
  37. {
  38. testName: "no existing endpoints",
  39. serviceName: "foo",
  40. ip: "1.2.3.4",
  41. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  42. endpoints: nil,
  43. expectUpdate: &api.Endpoints{
  44. ObjectMeta: om("foo"),
  45. Subsets: []api.EndpointSubset{{
  46. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  47. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  48. }},
  49. },
  50. },
  51. {
  52. testName: "existing endpoints satisfy",
  53. serviceName: "foo",
  54. ip: "1.2.3.4",
  55. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  56. endpoints: &api.EndpointsList{
  57. Items: []api.Endpoints{{
  58. ObjectMeta: om("foo"),
  59. Subsets: []api.EndpointSubset{{
  60. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  61. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  62. }},
  63. }},
  64. },
  65. },
  66. {
  67. testName: "existing endpoints satisfy but too many",
  68. serviceName: "foo",
  69. ip: "1.2.3.4",
  70. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  71. endpoints: &api.EndpointsList{
  72. Items: []api.Endpoints{{
  73. ObjectMeta: om("foo"),
  74. Subsets: []api.EndpointSubset{{
  75. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}, {IP: "4.3.2.1"}},
  76. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  77. }},
  78. }},
  79. },
  80. expectUpdate: &api.Endpoints{
  81. ObjectMeta: om("foo"),
  82. Subsets: []api.EndpointSubset{{
  83. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  84. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  85. }},
  86. },
  87. },
  88. {
  89. testName: "existing endpoints satisfy but too many + extra masters",
  90. serviceName: "foo",
  91. ip: "1.2.3.4",
  92. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  93. additionalMasters: 3,
  94. endpoints: &api.EndpointsList{
  95. Items: []api.Endpoints{{
  96. ObjectMeta: om("foo"),
  97. Subsets: []api.EndpointSubset{{
  98. Addresses: []api.EndpointAddress{
  99. {IP: "1.2.3.4"},
  100. {IP: "4.3.2.1"},
  101. {IP: "4.3.2.2"},
  102. {IP: "4.3.2.3"},
  103. {IP: "4.3.2.4"},
  104. },
  105. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  106. }},
  107. }},
  108. },
  109. expectUpdate: &api.Endpoints{
  110. ObjectMeta: om("foo"),
  111. Subsets: []api.EndpointSubset{{
  112. Addresses: []api.EndpointAddress{
  113. {IP: "1.2.3.4"},
  114. {IP: "4.3.2.2"},
  115. {IP: "4.3.2.3"},
  116. {IP: "4.3.2.4"},
  117. },
  118. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  119. }},
  120. },
  121. },
  122. {
  123. testName: "existing endpoints satisfy but too many + extra masters + delete first",
  124. serviceName: "foo",
  125. ip: "4.3.2.4",
  126. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  127. additionalMasters: 3,
  128. endpoints: &api.EndpointsList{
  129. Items: []api.Endpoints{{
  130. ObjectMeta: om("foo"),
  131. Subsets: []api.EndpointSubset{{
  132. Addresses: []api.EndpointAddress{
  133. {IP: "1.2.3.4"},
  134. {IP: "4.3.2.1"},
  135. {IP: "4.3.2.2"},
  136. {IP: "4.3.2.3"},
  137. {IP: "4.3.2.4"},
  138. },
  139. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  140. }},
  141. }},
  142. },
  143. expectUpdate: &api.Endpoints{
  144. ObjectMeta: om("foo"),
  145. Subsets: []api.EndpointSubset{{
  146. Addresses: []api.EndpointAddress{
  147. {IP: "4.3.2.1"},
  148. {IP: "4.3.2.2"},
  149. {IP: "4.3.2.3"},
  150. {IP: "4.3.2.4"},
  151. },
  152. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  153. }},
  154. },
  155. },
  156. {
  157. testName: "existing endpoints satisfy and endpoint addresses length less than master count",
  158. serviceName: "foo",
  159. ip: "4.3.2.2",
  160. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  161. additionalMasters: 3,
  162. endpoints: &api.EndpointsList{
  163. Items: []api.Endpoints{{
  164. ObjectMeta: om("foo"),
  165. Subsets: []api.EndpointSubset{{
  166. Addresses: []api.EndpointAddress{
  167. {IP: "4.3.2.1"},
  168. {IP: "4.3.2.2"},
  169. },
  170. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  171. }},
  172. }},
  173. },
  174. expectUpdate: nil,
  175. },
  176. {
  177. testName: "existing endpoints current IP missing and address length less than master count",
  178. serviceName: "foo",
  179. ip: "4.3.2.2",
  180. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  181. additionalMasters: 3,
  182. endpoints: &api.EndpointsList{
  183. Items: []api.Endpoints{{
  184. ObjectMeta: om("foo"),
  185. Subsets: []api.EndpointSubset{{
  186. Addresses: []api.EndpointAddress{
  187. {IP: "4.3.2.1"},
  188. },
  189. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  190. }},
  191. }},
  192. },
  193. expectUpdate: &api.Endpoints{
  194. ObjectMeta: om("foo"),
  195. Subsets: []api.EndpointSubset{{
  196. Addresses: []api.EndpointAddress{
  197. {IP: "4.3.2.1"},
  198. {IP: "4.3.2.2"},
  199. },
  200. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  201. }},
  202. },
  203. },
  204. {
  205. testName: "existing endpoints wrong name",
  206. serviceName: "foo",
  207. ip: "1.2.3.4",
  208. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  209. endpoints: &api.EndpointsList{
  210. Items: []api.Endpoints{{
  211. ObjectMeta: om("bar"),
  212. Subsets: []api.EndpointSubset{{
  213. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  214. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  215. }},
  216. }},
  217. },
  218. expectUpdate: &api.Endpoints{
  219. ObjectMeta: om("foo"),
  220. Subsets: []api.EndpointSubset{{
  221. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  222. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  223. }},
  224. },
  225. },
  226. {
  227. testName: "existing endpoints wrong IP",
  228. serviceName: "foo",
  229. ip: "1.2.3.4",
  230. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  231. endpoints: &api.EndpointsList{
  232. Items: []api.Endpoints{{
  233. ObjectMeta: om("foo"),
  234. Subsets: []api.EndpointSubset{{
  235. Addresses: []api.EndpointAddress{{IP: "4.3.2.1"}},
  236. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  237. }},
  238. }},
  239. },
  240. expectUpdate: &api.Endpoints{
  241. ObjectMeta: om("foo"),
  242. Subsets: []api.EndpointSubset{{
  243. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  244. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  245. }},
  246. },
  247. },
  248. {
  249. testName: "existing endpoints wrong port",
  250. serviceName: "foo",
  251. ip: "1.2.3.4",
  252. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  253. endpoints: &api.EndpointsList{
  254. Items: []api.Endpoints{{
  255. ObjectMeta: om("foo"),
  256. Subsets: []api.EndpointSubset{{
  257. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  258. Ports: []api.EndpointPort{{Name: "foo", Port: 9090, Protocol: "TCP"}},
  259. }},
  260. }},
  261. },
  262. expectUpdate: &api.Endpoints{
  263. ObjectMeta: om("foo"),
  264. Subsets: []api.EndpointSubset{{
  265. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  266. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  267. }},
  268. },
  269. },
  270. {
  271. testName: "existing endpoints wrong protocol",
  272. serviceName: "foo",
  273. ip: "1.2.3.4",
  274. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  275. endpoints: &api.EndpointsList{
  276. Items: []api.Endpoints{{
  277. ObjectMeta: om("foo"),
  278. Subsets: []api.EndpointSubset{{
  279. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  280. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "UDP"}},
  281. }},
  282. }},
  283. },
  284. expectUpdate: &api.Endpoints{
  285. ObjectMeta: om("foo"),
  286. Subsets: []api.EndpointSubset{{
  287. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  288. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  289. }},
  290. },
  291. },
  292. {
  293. testName: "existing endpoints wrong port name",
  294. serviceName: "foo",
  295. ip: "1.2.3.4",
  296. endpointPorts: []api.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}},
  297. endpoints: &api.EndpointsList{
  298. Items: []api.Endpoints{{
  299. ObjectMeta: om("foo"),
  300. Subsets: []api.EndpointSubset{{
  301. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  302. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  303. }},
  304. }},
  305. },
  306. expectUpdate: &api.Endpoints{
  307. ObjectMeta: om("foo"),
  308. Subsets: []api.EndpointSubset{{
  309. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  310. Ports: []api.EndpointPort{{Name: "baz", Port: 8080, Protocol: "TCP"}},
  311. }},
  312. },
  313. },
  314. {
  315. testName: "existing endpoints extra service ports satisfy",
  316. serviceName: "foo",
  317. ip: "1.2.3.4",
  318. endpointPorts: []api.EndpointPort{
  319. {Name: "foo", Port: 8080, Protocol: "TCP"},
  320. {Name: "bar", Port: 1000, Protocol: "TCP"},
  321. {Name: "baz", Port: 1010, Protocol: "TCP"},
  322. },
  323. endpoints: &api.EndpointsList{
  324. Items: []api.Endpoints{{
  325. ObjectMeta: om("foo"),
  326. Subsets: []api.EndpointSubset{{
  327. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  328. Ports: []api.EndpointPort{
  329. {Name: "foo", Port: 8080, Protocol: "TCP"},
  330. {Name: "bar", Port: 1000, Protocol: "TCP"},
  331. {Name: "baz", Port: 1010, Protocol: "TCP"},
  332. },
  333. }},
  334. }},
  335. },
  336. },
  337. {
  338. testName: "existing endpoints extra service ports missing port",
  339. serviceName: "foo",
  340. ip: "1.2.3.4",
  341. endpointPorts: []api.EndpointPort{
  342. {Name: "foo", Port: 8080, Protocol: "TCP"},
  343. {Name: "bar", Port: 1000, Protocol: "TCP"},
  344. },
  345. endpoints: &api.EndpointsList{
  346. Items: []api.Endpoints{{
  347. ObjectMeta: om("foo"),
  348. Subsets: []api.EndpointSubset{{
  349. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  350. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  351. }},
  352. }},
  353. },
  354. expectUpdate: &api.Endpoints{
  355. ObjectMeta: om("foo"),
  356. Subsets: []api.EndpointSubset{{
  357. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  358. Ports: []api.EndpointPort{
  359. {Name: "foo", Port: 8080, Protocol: "TCP"},
  360. {Name: "bar", Port: 1000, Protocol: "TCP"},
  361. },
  362. }},
  363. },
  364. },
  365. }
  366. for _, test := range reconcile_tests {
  367. registry := &registrytest.EndpointRegistry{
  368. Endpoints: test.endpoints,
  369. }
  370. reconciler := NewMasterCountEndpointReconciler(test.additionalMasters+1, registry)
  371. err := reconciler.ReconcileEndpoints(test.serviceName, net.ParseIP(test.ip), test.endpointPorts, true)
  372. if err != nil {
  373. t.Errorf("case %q: unexpected error: %v", test.testName, err)
  374. }
  375. if test.expectUpdate != nil {
  376. if len(registry.Updates) != 1 {
  377. t.Errorf("case %q: unexpected updates: %v", test.testName, registry.Updates)
  378. } else if e, a := test.expectUpdate, &registry.Updates[0]; !reflect.DeepEqual(e, a) {
  379. t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a)
  380. }
  381. }
  382. if test.expectUpdate == nil && len(registry.Updates) > 0 {
  383. t.Errorf("case %q: no update expected, yet saw: %v", test.testName, registry.Updates)
  384. }
  385. }
  386. non_reconcile_tests := []struct {
  387. testName string
  388. serviceName string
  389. ip string
  390. endpointPorts []api.EndpointPort
  391. additionalMasters int
  392. endpoints *api.EndpointsList
  393. expectUpdate *api.Endpoints // nil means none expected
  394. }{
  395. {
  396. testName: "existing endpoints extra service ports missing port no update",
  397. serviceName: "foo",
  398. ip: "1.2.3.4",
  399. endpointPorts: []api.EndpointPort{
  400. {Name: "foo", Port: 8080, Protocol: "TCP"},
  401. {Name: "bar", Port: 1000, Protocol: "TCP"},
  402. },
  403. endpoints: &api.EndpointsList{
  404. Items: []api.Endpoints{{
  405. ObjectMeta: om("foo"),
  406. Subsets: []api.EndpointSubset{{
  407. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  408. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  409. }},
  410. }},
  411. },
  412. expectUpdate: nil,
  413. },
  414. {
  415. testName: "existing endpoints extra service ports, wrong ports, wrong IP",
  416. serviceName: "foo",
  417. ip: "1.2.3.4",
  418. endpointPorts: []api.EndpointPort{
  419. {Name: "foo", Port: 8080, Protocol: "TCP"},
  420. {Name: "bar", Port: 1000, Protocol: "TCP"},
  421. },
  422. endpoints: &api.EndpointsList{
  423. Items: []api.Endpoints{{
  424. ObjectMeta: om("foo"),
  425. Subsets: []api.EndpointSubset{{
  426. Addresses: []api.EndpointAddress{{IP: "4.3.2.1"}},
  427. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  428. }},
  429. }},
  430. },
  431. expectUpdate: &api.Endpoints{
  432. ObjectMeta: om("foo"),
  433. Subsets: []api.EndpointSubset{{
  434. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  435. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  436. }},
  437. },
  438. },
  439. {
  440. testName: "no existing endpoints",
  441. serviceName: "foo",
  442. ip: "1.2.3.4",
  443. endpointPorts: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  444. endpoints: nil,
  445. expectUpdate: &api.Endpoints{
  446. ObjectMeta: om("foo"),
  447. Subsets: []api.EndpointSubset{{
  448. Addresses: []api.EndpointAddress{{IP: "1.2.3.4"}},
  449. Ports: []api.EndpointPort{{Name: "foo", Port: 8080, Protocol: "TCP"}},
  450. }},
  451. },
  452. },
  453. }
  454. for _, test := range non_reconcile_tests {
  455. registry := &registrytest.EndpointRegistry{
  456. Endpoints: test.endpoints,
  457. }
  458. reconciler := NewMasterCountEndpointReconciler(test.additionalMasters+1, registry)
  459. err := reconciler.ReconcileEndpoints(test.serviceName, net.ParseIP(test.ip), test.endpointPorts, false)
  460. if err != nil {
  461. t.Errorf("case %q: unexpected error: %v", test.testName, err)
  462. }
  463. if test.expectUpdate != nil {
  464. if len(registry.Updates) != 1 {
  465. t.Errorf("case %q: unexpected updates: %v", test.testName, registry.Updates)
  466. } else if e, a := test.expectUpdate, &registry.Updates[0]; !reflect.DeepEqual(e, a) {
  467. t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a)
  468. }
  469. }
  470. if test.expectUpdate == nil && len(registry.Updates) > 0 {
  471. t.Errorf("case %q: no update expected, yet saw: %v", test.testName, registry.Updates)
  472. }
  473. }
  474. }
  475. func TestCreateOrUpdateMasterService(t *testing.T) {
  476. ns := api.NamespaceDefault
  477. om := func(name string) api.ObjectMeta {
  478. return api.ObjectMeta{Namespace: ns, Name: name}
  479. }
  480. create_tests := []struct {
  481. testName string
  482. serviceName string
  483. servicePorts []api.ServicePort
  484. serviceType api.ServiceType
  485. expectCreate *api.Service // nil means none expected
  486. }{
  487. {
  488. testName: "service does not exist",
  489. serviceName: "foo",
  490. servicePorts: []api.ServicePort{
  491. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  492. },
  493. serviceType: api.ServiceTypeClusterIP,
  494. expectCreate: &api.Service{
  495. ObjectMeta: om("foo"),
  496. Spec: api.ServiceSpec{
  497. Ports: []api.ServicePort{
  498. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  499. },
  500. Selector: nil,
  501. ClusterIP: "1.2.3.4",
  502. SessionAffinity: api.ServiceAffinityClientIP,
  503. Type: api.ServiceTypeClusterIP,
  504. },
  505. },
  506. },
  507. }
  508. for _, test := range create_tests {
  509. master := Controller{}
  510. registry := &registrytest.ServiceRegistry{
  511. Err: errors.New("unable to get svc"),
  512. }
  513. master.ServiceRegistry = registry
  514. master.CreateOrUpdateMasterServiceIfNeeded(test.serviceName, net.ParseIP("1.2.3.4"), test.servicePorts, test.serviceType, false)
  515. if test.expectCreate != nil {
  516. if len(registry.List.Items) != 1 {
  517. t.Errorf("case %q: unexpected creations: %v", test.testName, registry.List.Items)
  518. } else if e, a := test.expectCreate.Spec, registry.List.Items[0].Spec; !reflect.DeepEqual(e, a) {
  519. t.Errorf("case %q: expected create:\n%#v\ngot:\n%#v\n", test.testName, e, a)
  520. }
  521. }
  522. if test.expectCreate == nil && len(registry.List.Items) > 1 {
  523. t.Errorf("case %q: no create expected, yet saw: %v", test.testName, registry.List.Items)
  524. }
  525. }
  526. reconcile_tests := []struct {
  527. testName string
  528. serviceName string
  529. servicePorts []api.ServicePort
  530. serviceType api.ServiceType
  531. service *api.Service
  532. expectUpdate *api.Service // nil means none expected
  533. }{
  534. {
  535. testName: "service definition wrong port",
  536. serviceName: "foo",
  537. servicePorts: []api.ServicePort{
  538. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  539. },
  540. serviceType: api.ServiceTypeClusterIP,
  541. service: &api.Service{
  542. ObjectMeta: om("foo"),
  543. Spec: api.ServiceSpec{
  544. Ports: []api.ServicePort{
  545. {Name: "foo", Port: 8000, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  546. },
  547. Selector: nil,
  548. ClusterIP: "1.2.3.4",
  549. SessionAffinity: api.ServiceAffinityClientIP,
  550. Type: api.ServiceTypeClusterIP,
  551. },
  552. },
  553. expectUpdate: &api.Service{
  554. ObjectMeta: om("foo"),
  555. Spec: api.ServiceSpec{
  556. Ports: []api.ServicePort{
  557. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  558. },
  559. Selector: nil,
  560. ClusterIP: "1.2.3.4",
  561. SessionAffinity: api.ServiceAffinityClientIP,
  562. Type: api.ServiceTypeClusterIP,
  563. },
  564. },
  565. },
  566. {
  567. testName: "service definition missing port",
  568. serviceName: "foo",
  569. servicePorts: []api.ServicePort{
  570. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  571. {Name: "baz", Port: 1000, Protocol: "TCP", TargetPort: intstr.FromInt(1000)},
  572. },
  573. serviceType: api.ServiceTypeClusterIP,
  574. service: &api.Service{
  575. ObjectMeta: om("foo"),
  576. Spec: api.ServiceSpec{
  577. Ports: []api.ServicePort{
  578. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  579. },
  580. Selector: nil,
  581. ClusterIP: "1.2.3.4",
  582. SessionAffinity: api.ServiceAffinityClientIP,
  583. Type: api.ServiceTypeClusterIP,
  584. },
  585. },
  586. expectUpdate: &api.Service{
  587. ObjectMeta: om("foo"),
  588. Spec: api.ServiceSpec{
  589. Ports: []api.ServicePort{
  590. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  591. {Name: "baz", Port: 1000, Protocol: "TCP", TargetPort: intstr.FromInt(1000)},
  592. },
  593. Selector: nil,
  594. ClusterIP: "1.2.3.4",
  595. SessionAffinity: api.ServiceAffinityClientIP,
  596. Type: api.ServiceTypeClusterIP,
  597. },
  598. },
  599. },
  600. {
  601. testName: "service definition incorrect port",
  602. serviceName: "foo",
  603. servicePorts: []api.ServicePort{
  604. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  605. },
  606. serviceType: api.ServiceTypeClusterIP,
  607. service: &api.Service{
  608. ObjectMeta: om("foo"),
  609. Spec: api.ServiceSpec{
  610. Ports: []api.ServicePort{
  611. {Name: "bar", Port: 1000, Protocol: "UDP", TargetPort: intstr.FromInt(1000)},
  612. },
  613. Selector: nil,
  614. ClusterIP: "1.2.3.4",
  615. SessionAffinity: api.ServiceAffinityClientIP,
  616. Type: api.ServiceTypeClusterIP,
  617. },
  618. },
  619. expectUpdate: &api.Service{
  620. ObjectMeta: om("foo"),
  621. Spec: api.ServiceSpec{
  622. Ports: []api.ServicePort{
  623. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  624. },
  625. Selector: nil,
  626. ClusterIP: "1.2.3.4",
  627. SessionAffinity: api.ServiceAffinityClientIP,
  628. Type: api.ServiceTypeClusterIP,
  629. },
  630. },
  631. },
  632. {
  633. testName: "service definition incorrect port name",
  634. serviceName: "foo",
  635. servicePorts: []api.ServicePort{
  636. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  637. },
  638. serviceType: api.ServiceTypeClusterIP,
  639. service: &api.Service{
  640. ObjectMeta: om("foo"),
  641. Spec: api.ServiceSpec{
  642. Ports: []api.ServicePort{
  643. {Name: "foo", Port: 1000, Protocol: "UDP", TargetPort: intstr.FromInt(1000)},
  644. },
  645. Selector: nil,
  646. ClusterIP: "1.2.3.4",
  647. SessionAffinity: api.ServiceAffinityClientIP,
  648. Type: api.ServiceTypeClusterIP,
  649. },
  650. },
  651. expectUpdate: &api.Service{
  652. ObjectMeta: om("foo"),
  653. Spec: api.ServiceSpec{
  654. Ports: []api.ServicePort{
  655. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  656. },
  657. Selector: nil,
  658. ClusterIP: "1.2.3.4",
  659. SessionAffinity: api.ServiceAffinityClientIP,
  660. Type: api.ServiceTypeClusterIP,
  661. },
  662. },
  663. },
  664. {
  665. testName: "service definition incorrect target port",
  666. serviceName: "foo",
  667. servicePorts: []api.ServicePort{
  668. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  669. },
  670. serviceType: api.ServiceTypeClusterIP,
  671. service: &api.Service{
  672. ObjectMeta: om("foo"),
  673. Spec: api.ServiceSpec{
  674. Ports: []api.ServicePort{
  675. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(1000)},
  676. },
  677. Selector: nil,
  678. ClusterIP: "1.2.3.4",
  679. SessionAffinity: api.ServiceAffinityClientIP,
  680. Type: api.ServiceTypeClusterIP,
  681. },
  682. },
  683. expectUpdate: &api.Service{
  684. ObjectMeta: om("foo"),
  685. Spec: api.ServiceSpec{
  686. Ports: []api.ServicePort{
  687. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  688. },
  689. Selector: nil,
  690. ClusterIP: "1.2.3.4",
  691. SessionAffinity: api.ServiceAffinityClientIP,
  692. Type: api.ServiceTypeClusterIP,
  693. },
  694. },
  695. },
  696. {
  697. testName: "service definition incorrect protocol",
  698. serviceName: "foo",
  699. servicePorts: []api.ServicePort{
  700. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  701. },
  702. serviceType: api.ServiceTypeClusterIP,
  703. service: &api.Service{
  704. ObjectMeta: om("foo"),
  705. Spec: api.ServiceSpec{
  706. Ports: []api.ServicePort{
  707. {Name: "foo", Port: 8080, Protocol: "UDP", TargetPort: intstr.FromInt(8080)},
  708. },
  709. Selector: nil,
  710. ClusterIP: "1.2.3.4",
  711. SessionAffinity: api.ServiceAffinityClientIP,
  712. Type: api.ServiceTypeClusterIP,
  713. },
  714. },
  715. expectUpdate: &api.Service{
  716. ObjectMeta: om("foo"),
  717. Spec: api.ServiceSpec{
  718. Ports: []api.ServicePort{
  719. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  720. },
  721. Selector: nil,
  722. ClusterIP: "1.2.3.4",
  723. SessionAffinity: api.ServiceAffinityClientIP,
  724. Type: api.ServiceTypeClusterIP,
  725. },
  726. },
  727. },
  728. {
  729. testName: "service definition has incorrect type",
  730. serviceName: "foo",
  731. servicePorts: []api.ServicePort{
  732. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  733. },
  734. serviceType: api.ServiceTypeClusterIP,
  735. service: &api.Service{
  736. ObjectMeta: om("foo"),
  737. Spec: api.ServiceSpec{
  738. Ports: []api.ServicePort{
  739. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  740. },
  741. Selector: nil,
  742. ClusterIP: "1.2.3.4",
  743. SessionAffinity: api.ServiceAffinityClientIP,
  744. Type: api.ServiceTypeNodePort,
  745. },
  746. },
  747. expectUpdate: &api.Service{
  748. ObjectMeta: om("foo"),
  749. Spec: api.ServiceSpec{
  750. Ports: []api.ServicePort{
  751. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  752. },
  753. Selector: nil,
  754. ClusterIP: "1.2.3.4",
  755. SessionAffinity: api.ServiceAffinityClientIP,
  756. Type: api.ServiceTypeClusterIP,
  757. },
  758. },
  759. },
  760. {
  761. testName: "service definition satisfies",
  762. serviceName: "foo",
  763. servicePorts: []api.ServicePort{
  764. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  765. },
  766. serviceType: api.ServiceTypeClusterIP,
  767. service: &api.Service{
  768. ObjectMeta: om("foo"),
  769. Spec: api.ServiceSpec{
  770. Ports: []api.ServicePort{
  771. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  772. },
  773. Selector: nil,
  774. ClusterIP: "1.2.3.4",
  775. SessionAffinity: api.ServiceAffinityClientIP,
  776. Type: api.ServiceTypeClusterIP,
  777. },
  778. },
  779. expectUpdate: nil,
  780. },
  781. }
  782. for _, test := range reconcile_tests {
  783. master := Controller{}
  784. registry := &registrytest.ServiceRegistry{
  785. Service: test.service,
  786. }
  787. master.ServiceRegistry = registry
  788. err := master.CreateOrUpdateMasterServiceIfNeeded(test.serviceName, net.ParseIP("1.2.3.4"), test.servicePorts, test.serviceType, true)
  789. if err != nil {
  790. t.Errorf("case %q: unexpected error: %v", test.testName, err)
  791. }
  792. if test.expectUpdate != nil {
  793. if len(registry.Updates) != 1 {
  794. t.Errorf("case %q: unexpected updates: %v", test.testName, registry.Updates)
  795. } else if e, a := test.expectUpdate, &registry.Updates[0]; !reflect.DeepEqual(e, a) {
  796. t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a)
  797. }
  798. }
  799. if test.expectUpdate == nil && len(registry.Updates) > 0 {
  800. t.Errorf("case %q: no update expected, yet saw: %v", test.testName, registry.Updates)
  801. }
  802. }
  803. non_reconcile_tests := []struct {
  804. testName string
  805. serviceName string
  806. servicePorts []api.ServicePort
  807. serviceType api.ServiceType
  808. service *api.Service
  809. expectUpdate *api.Service // nil means none expected
  810. }{
  811. {
  812. testName: "service definition wrong port, no expected update",
  813. serviceName: "foo",
  814. servicePorts: []api.ServicePort{
  815. {Name: "foo", Port: 8080, Protocol: "TCP", TargetPort: intstr.FromInt(8080)},
  816. },
  817. serviceType: api.ServiceTypeClusterIP,
  818. service: &api.Service{
  819. ObjectMeta: om("foo"),
  820. Spec: api.ServiceSpec{
  821. Ports: []api.ServicePort{
  822. {Name: "foo", Port: 1000, Protocol: "TCP", TargetPort: intstr.FromInt(1000)},
  823. },
  824. Selector: nil,
  825. ClusterIP: "1.2.3.4",
  826. SessionAffinity: api.ServiceAffinityClientIP,
  827. Type: api.ServiceTypeClusterIP,
  828. },
  829. },
  830. expectUpdate: nil,
  831. },
  832. }
  833. for _, test := range non_reconcile_tests {
  834. master := Controller{}
  835. registry := &registrytest.ServiceRegistry{
  836. Service: test.service,
  837. }
  838. master.ServiceRegistry = registry
  839. err := master.CreateOrUpdateMasterServiceIfNeeded(test.serviceName, net.ParseIP("1.2.3.4"), test.servicePorts, test.serviceType, false)
  840. if err != nil {
  841. t.Errorf("case %q: unexpected error: %v", test.testName, err)
  842. }
  843. if test.expectUpdate != nil {
  844. if len(registry.Updates) != 1 {
  845. t.Errorf("case %q: unexpected updates: %v", test.testName, registry.Updates)
  846. } else if e, a := test.expectUpdate, &registry.Updates[0]; !reflect.DeepEqual(e, a) {
  847. t.Errorf("case %q: expected update:\n%#v\ngot:\n%#v\n", test.testName, e, a)
  848. }
  849. }
  850. if test.expectUpdate == nil && len(registry.Updates) > 0 {
  851. t.Errorf("case %q: no update expected, yet saw: %v", test.testName, registry.Updates)
  852. }
  853. }
  854. }