You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

710 lines
21 KiB

  1. /*
  2. *
  3. * Copyright 2019 gRPC authors.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. package xds
  19. import (
  20. "encoding/json"
  21. "reflect"
  22. "sync"
  23. "testing"
  24. "time"
  25. "google.golang.org/grpc/internal/grpctest"
  26. "google.golang.org/grpc/internal/leakcheck"
  27. xdspb "github.com/envoyproxy/go-control-plane/envoy/api/v2"
  28. "google.golang.org/grpc/balancer"
  29. "google.golang.org/grpc/connectivity"
  30. "google.golang.org/grpc/resolver"
  31. )
  32. var lbABuilder *balancerABuilder
  33. func init() {
  34. lbABuilder = &balancerABuilder{}
  35. balancer.Register(lbABuilder)
  36. balancer.Register(&balancerBBuilder{})
  37. }
  38. type s struct{}
  39. func (s) Teardown(t *testing.T) {
  40. leakcheck.Check(t)
  41. }
  42. func Test(t *testing.T) {
  43. grpctest.RunSubTests(t, s{})
  44. }
  45. type lbPolicy string
  46. const (
  47. fakeBalancerA lbPolicy = "fake_balancer_A"
  48. fakeBalancerB lbPolicy = "fake_balancer_B"
  49. fakeBalancerC lbPolicy = "fake_balancer_C"
  50. )
  51. var (
  52. testBalancerNameFooBar = "foo.bar"
  53. testBalancerConfigFooBar, _ = json.Marshal(&testBalancerConfig{
  54. BalancerName: testBalancerNameFooBar,
  55. ChildPolicy: []lbPolicy{fakeBalancerA},
  56. FallbackPolicy: []lbPolicy{fakeBalancerA},
  57. })
  58. specialAddrForBalancerA = resolver.Address{Addr: "this.is.balancer.A"}
  59. specialAddrForBalancerB = resolver.Address{Addr: "this.is.balancer.B"}
  60. // mu protects the access of latestFakeEdsBalancer
  61. mu sync.Mutex
  62. latestFakeEdsBalancer *fakeEDSBalancer
  63. )
  64. type testBalancerConfig struct {
  65. BalancerName string `json:"balancerName,omitempty"`
  66. ChildPolicy []lbPolicy `json:"childPolicy,omitempty"`
  67. FallbackPolicy []lbPolicy `json:"fallbackPolicy,omitempty"`
  68. }
  69. func (l *lbPolicy) UnmarshalJSON(b []byte) error {
  70. // no need to implement, not used.
  71. return nil
  72. }
  73. func (l lbPolicy) MarshalJSON() ([]byte, error) {
  74. m := make(map[string]struct{})
  75. m[string(l)] = struct{}{}
  76. return json.Marshal(m)
  77. }
  78. type balancerABuilder struct {
  79. mu sync.Mutex
  80. lastBalancer *balancerA
  81. }
  82. func (b *balancerABuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
  83. b.mu.Lock()
  84. b.lastBalancer = &balancerA{cc: cc, subconnStateChange: make(chan *scStateChange, 10)}
  85. b.mu.Unlock()
  86. return b.lastBalancer
  87. }
  88. func (b *balancerABuilder) Name() string {
  89. return string(fakeBalancerA)
  90. }
  91. func (b *balancerABuilder) getLastBalancer() *balancerA {
  92. b.mu.Lock()
  93. defer b.mu.Unlock()
  94. return b.lastBalancer
  95. }
  96. func (b *balancerABuilder) clearLastBalancer() {
  97. b.mu.Lock()
  98. defer b.mu.Unlock()
  99. b.lastBalancer = nil
  100. }
  101. type balancerBBuilder struct{}
  102. func (b *balancerBBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
  103. return &balancerB{cc: cc}
  104. }
  105. func (*balancerBBuilder) Name() string {
  106. return string(fakeBalancerB)
  107. }
  108. type balancerA struct {
  109. cc balancer.ClientConn
  110. subconnStateChange chan *scStateChange
  111. }
  112. func (b *balancerA) HandleSubConnStateChange(sc balancer.SubConn, state connectivity.State) {
  113. b.subconnStateChange <- &scStateChange{sc: sc, state: state}
  114. }
  115. func (b *balancerA) HandleResolvedAddrs(addrs []resolver.Address, err error) {
  116. _, _ = b.cc.NewSubConn(append(addrs, specialAddrForBalancerA), balancer.NewSubConnOptions{})
  117. }
  118. func (b *balancerA) Close() {}
  119. type balancerB struct {
  120. cc balancer.ClientConn
  121. }
  122. func (balancerB) HandleSubConnStateChange(sc balancer.SubConn, state connectivity.State) {
  123. panic("implement me")
  124. }
  125. func (b *balancerB) HandleResolvedAddrs(addrs []resolver.Address, err error) {
  126. _, _ = b.cc.NewSubConn(append(addrs, specialAddrForBalancerB), balancer.NewSubConnOptions{})
  127. }
  128. func (balancerB) Close() {}
  129. func newTestClientConn() *testClientConn {
  130. return &testClientConn{
  131. newSubConns: make(chan []resolver.Address, 10),
  132. }
  133. }
  134. type testClientConn struct {
  135. newSubConns chan []resolver.Address
  136. }
  137. func (t *testClientConn) NewSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
  138. t.newSubConns <- addrs
  139. return nil, nil
  140. }
  141. func (testClientConn) RemoveSubConn(balancer.SubConn) {
  142. }
  143. func (testClientConn) UpdateBalancerState(s connectivity.State, p balancer.Picker) {
  144. }
  145. func (testClientConn) ResolveNow(resolver.ResolveNowOption) {}
  146. func (testClientConn) Target() string {
  147. return testServiceName
  148. }
  149. type scStateChange struct {
  150. sc balancer.SubConn
  151. state connectivity.State
  152. }
  153. type fakeEDSBalancer struct {
  154. cc balancer.ClientConn
  155. edsChan chan *xdspb.ClusterLoadAssignment
  156. childPolicy chan *loadBalancingConfig
  157. fallbackPolicy chan *loadBalancingConfig
  158. subconnStateChange chan *scStateChange
  159. }
  160. func (f *fakeEDSBalancer) HandleSubConnStateChange(sc balancer.SubConn, state connectivity.State) {
  161. f.subconnStateChange <- &scStateChange{sc: sc, state: state}
  162. }
  163. func (f *fakeEDSBalancer) Close() {
  164. mu.Lock()
  165. defer mu.Unlock()
  166. latestFakeEdsBalancer = nil
  167. }
  168. func (f *fakeEDSBalancer) HandleEDSResponse(edsResp *xdspb.ClusterLoadAssignment) {
  169. f.edsChan <- edsResp
  170. }
  171. func (f *fakeEDSBalancer) HandleChildPolicy(name string, config json.RawMessage) {
  172. f.childPolicy <- &loadBalancingConfig{
  173. Name: name,
  174. Config: config,
  175. }
  176. }
  177. func newFakeEDSBalancer(cc balancer.ClientConn) edsBalancerInterface {
  178. lb := &fakeEDSBalancer{
  179. cc: cc,
  180. edsChan: make(chan *xdspb.ClusterLoadAssignment, 10),
  181. childPolicy: make(chan *loadBalancingConfig, 10),
  182. fallbackPolicy: make(chan *loadBalancingConfig, 10),
  183. subconnStateChange: make(chan *scStateChange, 10),
  184. }
  185. mu.Lock()
  186. latestFakeEdsBalancer = lb
  187. mu.Unlock()
  188. return lb
  189. }
  190. func getLatestEdsBalancer() *fakeEDSBalancer {
  191. mu.Lock()
  192. defer mu.Unlock()
  193. return latestFakeEdsBalancer
  194. }
  195. type fakeSubConn struct{}
  196. func (*fakeSubConn) UpdateAddresses([]resolver.Address) {
  197. panic("implement me")
  198. }
  199. func (*fakeSubConn) Connect() {
  200. panic("implement me")
  201. }
  202. func (s) TestXdsBalanceHandleResolvedAddrs(t *testing.T) {
  203. startupTimeout = 500 * time.Millisecond
  204. defer func() { startupTimeout = defaultTimeout }()
  205. builder := balancer.Get("xds")
  206. cc := newTestClientConn()
  207. lb, ok := builder.Build(cc, balancer.BuildOptions{}).(*xdsBalancer)
  208. if !ok {
  209. t.Fatalf("unable to type assert to *xdsBalancer")
  210. }
  211. defer lb.Close()
  212. if err := lb.HandleBalancerConfig(json.RawMessage(testBalancerConfigFooBar)); err != nil {
  213. t.Fatalf("failed to HandleBalancerConfig(%v), due to err: %v", string(testBalancerConfigFooBar), err)
  214. }
  215. addrs := []resolver.Address{{Addr: "1.1.1.1:10001"}, {Addr: "2.2.2.2:10002"}, {Addr: "3.3.3.3:10003"}}
  216. for i := 0; i < 3; i++ {
  217. lb.HandleResolvedAddrs(addrs, nil)
  218. select {
  219. case nsc := <-cc.newSubConns:
  220. if !reflect.DeepEqual(append(addrs, specialAddrForBalancerA), nsc) {
  221. t.Fatalf("got new subconn address %v, want %v", nsc, append(addrs, specialAddrForBalancerA))
  222. }
  223. case <-time.After(2 * time.Second):
  224. t.Fatalf("timeout when geting new subconn result")
  225. }
  226. addrs = addrs[:2-i]
  227. }
  228. }
  229. func (s) TestXdsBalanceHandleBalancerConfigBalancerNameUpdate(t *testing.T) {
  230. startupTimeout = 500 * time.Millisecond
  231. originalNewEDSBalancer := newEDSBalancer
  232. newEDSBalancer = newFakeEDSBalancer
  233. defer func() {
  234. startupTimeout = defaultTimeout
  235. newEDSBalancer = originalNewEDSBalancer
  236. }()
  237. builder := balancer.Get("xds")
  238. cc := newTestClientConn()
  239. lb, ok := builder.Build(cc, balancer.BuildOptions{}).(*xdsBalancer)
  240. if !ok {
  241. t.Fatalf("unable to type assert to *xdsBalancer")
  242. }
  243. defer lb.Close()
  244. if err := lb.HandleBalancerConfig(json.RawMessage(testBalancerConfigFooBar)); err != nil {
  245. t.Fatalf("failed to HandleBalancerConfig(%v), due to err: %v", string(testBalancerConfigFooBar), err)
  246. }
  247. addrs := []resolver.Address{{Addr: "1.1.1.1:10001"}, {Addr: "2.2.2.2:10002"}, {Addr: "3.3.3.3:10003"}}
  248. lb.HandleResolvedAddrs(addrs, nil)
  249. // verify fallback takes over
  250. select {
  251. case nsc := <-cc.newSubConns:
  252. if !reflect.DeepEqual(append(addrs, specialAddrForBalancerA), nsc) {
  253. t.Fatalf("got new subconn address %v, want %v", nsc, append(addrs, specialAddrForBalancerA))
  254. }
  255. case <-time.After(2 * time.Second):
  256. t.Fatalf("timeout when geting new subconn result")
  257. }
  258. var cleanups []func()
  259. defer func() {
  260. for _, cleanup := range cleanups {
  261. cleanup()
  262. }
  263. }()
  264. // In the first iteration, an eds balancer takes over fallback balancer
  265. // In the second iteration, a new xds client takes over previous one.
  266. for i := 0; i < 2; i++ {
  267. addr, td, cleanup := setupServer(t)
  268. cleanups = append(cleanups, cleanup)
  269. workingBalancerConfig, _ := json.Marshal(&testBalancerConfig{
  270. BalancerName: addr,
  271. ChildPolicy: []lbPolicy{fakeBalancerA},
  272. FallbackPolicy: []lbPolicy{fakeBalancerA},
  273. })
  274. if err := lb.HandleBalancerConfig(json.RawMessage(workingBalancerConfig)); err != nil {
  275. t.Fatalf("failed to HandleBalancerConfig(%v), due to err: %v", string(workingBalancerConfig), err)
  276. }
  277. td.sendResp(&response{resp: testEDSRespWithoutEndpoints})
  278. var j int
  279. for j = 0; j < 10; j++ {
  280. if edsLB := getLatestEdsBalancer(); edsLB != nil { // edsLB won't change between the two iterations
  281. select {
  282. case gotEDS := <-edsLB.edsChan:
  283. if !reflect.DeepEqual(gotEDS, testClusterLoadAssignmentWithoutEndpoints) {
  284. t.Fatalf("edsBalancer got eds: %v, want %v", gotEDS, testClusterLoadAssignmentWithoutEndpoints)
  285. }
  286. case <-time.After(time.Second):
  287. t.Fatal("haven't got EDS update after 1s")
  288. }
  289. break
  290. }
  291. time.Sleep(100 * time.Millisecond)
  292. }
  293. if j == 10 {
  294. t.Fatal("edsBalancer instance has not been created or updated after 1s")
  295. }
  296. }
  297. }
  298. // switch child policy, lb stays the same
  299. // cds->eds or eds -> cds, restart xdsClient, lb stays the same
  300. func (s) TestXdsBalanceHandleBalancerConfigChildPolicyUpdate(t *testing.T) {
  301. originalNewEDSBalancer := newEDSBalancer
  302. newEDSBalancer = newFakeEDSBalancer
  303. defer func() {
  304. newEDSBalancer = originalNewEDSBalancer
  305. }()
  306. builder := balancer.Get("xds")
  307. cc := newTestClientConn()
  308. lb, ok := builder.Build(cc, balancer.BuildOptions{}).(*xdsBalancer)
  309. if !ok {
  310. t.Fatalf("unable to type assert to *xdsBalancer")
  311. }
  312. defer lb.Close()
  313. var cleanups []func()
  314. defer func() {
  315. for _, cleanup := range cleanups {
  316. cleanup()
  317. }
  318. }()
  319. for _, test := range []struct {
  320. cfg *testBalancerConfig
  321. responseToSend *xdspb.DiscoveryResponse
  322. expectedChildPolicy *loadBalancingConfig
  323. }{
  324. {
  325. cfg: &testBalancerConfig{
  326. ChildPolicy: []lbPolicy{fakeBalancerA},
  327. },
  328. responseToSend: testEDSRespWithoutEndpoints,
  329. expectedChildPolicy: &loadBalancingConfig{
  330. Name: string(fakeBalancerA),
  331. Config: json.RawMessage(`{}`),
  332. },
  333. },
  334. {
  335. cfg: &testBalancerConfig{
  336. ChildPolicy: []lbPolicy{fakeBalancerB},
  337. },
  338. expectedChildPolicy: &loadBalancingConfig{
  339. Name: string(fakeBalancerB),
  340. Config: json.RawMessage(`{}`),
  341. },
  342. },
  343. {
  344. cfg: &testBalancerConfig{},
  345. responseToSend: testCDSResp,
  346. expectedChildPolicy: &loadBalancingConfig{
  347. Name: "ROUND_ROBIN",
  348. },
  349. },
  350. } {
  351. addr, td, cleanup := setupServer(t)
  352. cleanups = append(cleanups, cleanup)
  353. test.cfg.BalancerName = addr
  354. workingBalancerConfig, _ := json.Marshal(test.cfg)
  355. if err := lb.HandleBalancerConfig(json.RawMessage(workingBalancerConfig)); err != nil {
  356. t.Fatalf("failed to HandleBalancerConfig(%v), due to err: %v", string(workingBalancerConfig), err)
  357. }
  358. if test.responseToSend != nil {
  359. td.sendResp(&response{resp: test.responseToSend})
  360. }
  361. var i int
  362. for i = 0; i < 10; i++ {
  363. if edsLB := getLatestEdsBalancer(); edsLB != nil {
  364. select {
  365. case childPolicy := <-edsLB.childPolicy:
  366. if !reflect.DeepEqual(childPolicy, test.expectedChildPolicy) {
  367. t.Fatalf("got childPolicy %v, want %v", childPolicy, test.expectedChildPolicy)
  368. }
  369. case <-time.After(time.Second):
  370. t.Fatal("haven't got policy update after 1s")
  371. }
  372. break
  373. }
  374. time.Sleep(100 * time.Millisecond)
  375. }
  376. if i == 10 {
  377. t.Fatal("edsBalancer instance has not been created or updated after 1s")
  378. }
  379. }
  380. }
  381. // not in fallback mode, overwrite fallback info.
  382. // in fallback mode, update config or switch balancer.
  383. func (s) TestXdsBalanceHandleBalancerConfigFallbackUpdate(t *testing.T) {
  384. originalNewEDSBalancer := newEDSBalancer
  385. newEDSBalancer = newFakeEDSBalancer
  386. defer func() {
  387. newEDSBalancer = originalNewEDSBalancer
  388. }()
  389. builder := balancer.Get("xds")
  390. cc := newTestClientConn()
  391. lb, ok := builder.Build(cc, balancer.BuildOptions{}).(*xdsBalancer)
  392. if !ok {
  393. t.Fatalf("unable to type assert to *xdsBalancer")
  394. }
  395. defer lb.Close()
  396. addr, td, cleanup := setupServer(t)
  397. cfg := &testBalancerConfig{
  398. BalancerName: addr,
  399. ChildPolicy: []lbPolicy{fakeBalancerA},
  400. FallbackPolicy: []lbPolicy{fakeBalancerA},
  401. }
  402. workingBalancerConfig, _ := json.Marshal(cfg)
  403. if err := lb.HandleBalancerConfig(json.RawMessage(workingBalancerConfig)); err != nil {
  404. t.Fatalf("failed to HandleBalancerConfig(%v), due to err: %v", string(workingBalancerConfig), err)
  405. }
  406. cfg.FallbackPolicy = []lbPolicy{fakeBalancerB}
  407. workingBalancerConfig, _ = json.Marshal(cfg)
  408. if err := lb.HandleBalancerConfig(json.RawMessage(workingBalancerConfig)); err != nil {
  409. t.Fatalf("failed to HandleBalancerConfig(%v), due to err: %v", string(workingBalancerConfig), err)
  410. }
  411. td.sendResp(&response{resp: testEDSRespWithoutEndpoints})
  412. var i int
  413. for i = 0; i < 10; i++ {
  414. if edsLB := getLatestEdsBalancer(); edsLB != nil {
  415. break
  416. }
  417. time.Sleep(100 * time.Millisecond)
  418. }
  419. if i == 10 {
  420. t.Fatal("edsBalancer instance has not been created and assigned to lb.xdsLB after 1s")
  421. }
  422. cleanup()
  423. addrs := []resolver.Address{{Addr: "1.1.1.1:10001"}, {Addr: "2.2.2.2:10002"}, {Addr: "3.3.3.3:10003"}}
  424. lb.HandleResolvedAddrs(addrs, nil)
  425. // verify fallback balancer B takes over
  426. select {
  427. case nsc := <-cc.newSubConns:
  428. if !reflect.DeepEqual(append(addrs, specialAddrForBalancerB), nsc) {
  429. t.Fatalf("got new subconn address %v, want %v", nsc, append(addrs, specialAddrForBalancerB))
  430. }
  431. case <-time.After(5 * time.Second):
  432. t.Fatalf("timeout when geting new subconn result")
  433. }
  434. cfg.FallbackPolicy = []lbPolicy{fakeBalancerA}
  435. workingBalancerConfig, _ = json.Marshal(cfg)
  436. if err := lb.HandleBalancerConfig(json.RawMessage(workingBalancerConfig)); err != nil {
  437. t.Fatalf("failed to HandleBalancerConfig(%v), due to err: %v", string(workingBalancerConfig), err)
  438. }
  439. // verify fallback balancer A takes over
  440. select {
  441. case nsc := <-cc.newSubConns:
  442. if !reflect.DeepEqual(append(addrs, specialAddrForBalancerA), nsc) {
  443. t.Fatalf("got new subconn address %v, want %v", nsc, append(addrs, specialAddrForBalancerA))
  444. }
  445. case <-time.After(2 * time.Second):
  446. t.Fatalf("timeout when geting new subconn result")
  447. }
  448. }
  449. func (s) TestXdsBalancerHandlerSubConnStateChange(t *testing.T) {
  450. originalNewEDSBalancer := newEDSBalancer
  451. newEDSBalancer = newFakeEDSBalancer
  452. defer func() {
  453. newEDSBalancer = originalNewEDSBalancer
  454. }()
  455. builder := balancer.Get("xds")
  456. cc := newTestClientConn()
  457. lb, ok := builder.Build(cc, balancer.BuildOptions{}).(*xdsBalancer)
  458. if !ok {
  459. t.Fatalf("unable to type assert to *xdsBalancer")
  460. }
  461. defer lb.Close()
  462. addr, td, cleanup := setupServer(t)
  463. defer cleanup()
  464. cfg := &testBalancerConfig{
  465. BalancerName: addr,
  466. ChildPolicy: []lbPolicy{fakeBalancerA},
  467. FallbackPolicy: []lbPolicy{fakeBalancerA},
  468. }
  469. workingBalancerConfig, _ := json.Marshal(cfg)
  470. if err := lb.HandleBalancerConfig(json.RawMessage(workingBalancerConfig)); err != nil {
  471. t.Fatalf("failed to HandleBalancerConfig(%v), due to err: %v", string(workingBalancerConfig), err)
  472. }
  473. td.sendResp(&response{resp: testEDSRespWithoutEndpoints})
  474. expectedScStateChange := &scStateChange{
  475. sc: &fakeSubConn{},
  476. state: connectivity.Ready,
  477. }
  478. var i int
  479. for i = 0; i < 10; i++ {
  480. if edsLB := getLatestEdsBalancer(); edsLB != nil {
  481. lb.HandleSubConnStateChange(expectedScStateChange.sc, expectedScStateChange.state)
  482. select {
  483. case scsc := <-edsLB.subconnStateChange:
  484. if !reflect.DeepEqual(scsc, expectedScStateChange) {
  485. t.Fatalf("got subconn state change %v, want %v", scsc, expectedScStateChange)
  486. }
  487. case <-time.After(time.Second):
  488. t.Fatal("haven't got subconn state change after 1s")
  489. }
  490. break
  491. }
  492. time.Sleep(100 * time.Millisecond)
  493. }
  494. if i == 10 {
  495. t.Fatal("edsBalancer instance has not been created and assigned to lb.xdsLB after 1s")
  496. }
  497. // lbAbuilder has a per binary record what's the last balanceA created. We need to clear the record
  498. // to make sure there's a new one created and get the pointer to it.
  499. lbABuilder.clearLastBalancer()
  500. cleanup()
  501. // switch to fallback
  502. // fallback balancer A takes over
  503. for i = 0; i < 10; i++ {
  504. if fblb := lbABuilder.getLastBalancer(); fblb != nil {
  505. lb.HandleSubConnStateChange(expectedScStateChange.sc, expectedScStateChange.state)
  506. select {
  507. case scsc := <-fblb.subconnStateChange:
  508. if !reflect.DeepEqual(scsc, expectedScStateChange) {
  509. t.Fatalf("got subconn state change %v, want %v", scsc, expectedScStateChange)
  510. }
  511. case <-time.After(time.Second):
  512. t.Fatal("haven't got subconn state change after 1s")
  513. }
  514. break
  515. }
  516. time.Sleep(100 * time.Millisecond)
  517. }
  518. if i == 10 {
  519. t.Fatal("balancerA instance has not been created after 1s")
  520. }
  521. }
  522. func (s) TestXdsBalancerFallbackSignalFromEdsBalancer(t *testing.T) {
  523. originalNewEDSBalancer := newEDSBalancer
  524. newEDSBalancer = newFakeEDSBalancer
  525. defer func() {
  526. newEDSBalancer = originalNewEDSBalancer
  527. }()
  528. builder := balancer.Get("xds")
  529. cc := newTestClientConn()
  530. lb, ok := builder.Build(cc, balancer.BuildOptions{}).(*xdsBalancer)
  531. if !ok {
  532. t.Fatalf("unable to type assert to *xdsBalancer")
  533. }
  534. defer lb.Close()
  535. addr, td, cleanup := setupServer(t)
  536. defer cleanup()
  537. cfg := &testBalancerConfig{
  538. BalancerName: addr,
  539. ChildPolicy: []lbPolicy{fakeBalancerA},
  540. FallbackPolicy: []lbPolicy{fakeBalancerA},
  541. }
  542. workingBalancerConfig, _ := json.Marshal(cfg)
  543. if err := lb.HandleBalancerConfig(json.RawMessage(workingBalancerConfig)); err != nil {
  544. t.Fatalf("failed to HandleBalancerConfig(%v), due to err: %v", string(workingBalancerConfig), err)
  545. }
  546. td.sendResp(&response{resp: testEDSRespWithoutEndpoints})
  547. expectedScStateChange := &scStateChange{
  548. sc: &fakeSubConn{},
  549. state: connectivity.Ready,
  550. }
  551. var i int
  552. for i = 0; i < 10; i++ {
  553. if edsLB := getLatestEdsBalancer(); edsLB != nil {
  554. lb.HandleSubConnStateChange(expectedScStateChange.sc, expectedScStateChange.state)
  555. select {
  556. case scsc := <-edsLB.subconnStateChange:
  557. if !reflect.DeepEqual(scsc, expectedScStateChange) {
  558. t.Fatalf("got subconn state change %v, want %v", scsc, expectedScStateChange)
  559. }
  560. case <-time.After(time.Second):
  561. t.Fatal("haven't got subconn state change after 1s")
  562. }
  563. break
  564. }
  565. time.Sleep(100 * time.Millisecond)
  566. }
  567. if i == 10 {
  568. t.Fatal("edsBalancer instance has not been created and assigned to lb.xdsLB after 1s")
  569. }
  570. // lbAbuilder has a per binary record what's the last balanceA created. We need to clear the record
  571. // to make sure there's a new one created and get the pointer to it.
  572. lbABuilder.clearLastBalancer()
  573. cleanup()
  574. // switch to fallback
  575. // fallback balancer A takes over
  576. for i = 0; i < 10; i++ {
  577. if fblb := lbABuilder.getLastBalancer(); fblb != nil {
  578. lb.HandleSubConnStateChange(expectedScStateChange.sc, expectedScStateChange.state)
  579. select {
  580. case scsc := <-fblb.subconnStateChange:
  581. if !reflect.DeepEqual(scsc, expectedScStateChange) {
  582. t.Fatalf("got subconn state change %v, want %v", scsc, expectedScStateChange)
  583. }
  584. case <-time.After(time.Second):
  585. t.Fatal("haven't got subconn state change after 1s")
  586. }
  587. break
  588. }
  589. time.Sleep(100 * time.Millisecond)
  590. }
  591. if i == 10 {
  592. t.Fatal("balancerA instance has not been created after 1s")
  593. }
  594. }
  595. func (s) TestXdsBalancerConfigParsingSelectingLBPolicy(t *testing.T) {
  596. tesCfg := &testBalancerConfig{
  597. BalancerName: "fake.foo.bar",
  598. ChildPolicy: []lbPolicy{fakeBalancerC, fakeBalancerA, fakeBalancerB}, // selects fakeBalancerA
  599. FallbackPolicy: []lbPolicy{fakeBalancerC, fakeBalancerB, fakeBalancerA}, // selects fakeBalancerB
  600. }
  601. js, _ := json.Marshal(tesCfg)
  602. var xdsCfg xdsConfig
  603. if err := json.Unmarshal(js, &xdsCfg); err != nil {
  604. t.Fatal("unable to unmarshal balancer config into xds config")
  605. }
  606. wantChildPolicy := &loadBalancingConfig{Name: string(fakeBalancerA), Config: json.RawMessage(`{}`)}
  607. if !reflect.DeepEqual(xdsCfg.ChildPolicy, wantChildPolicy) {
  608. t.Fatalf("got child policy %v, want %v", xdsCfg.ChildPolicy, wantChildPolicy)
  609. }
  610. wantFallbackPolicy := &loadBalancingConfig{Name: string(fakeBalancerB), Config: json.RawMessage(`{}`)}
  611. if !reflect.DeepEqual(xdsCfg.FallBackPolicy, wantFallbackPolicy) {
  612. t.Fatalf("got fallback policy %v, want %v", xdsCfg.FallBackPolicy, wantFallbackPolicy)
  613. }
  614. }