gracefulswitch_test.go 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133
  1. /*
  2. *
  3. * Copyright 2022 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 gracefulswitch
  19. import (
  20. "context"
  21. "fmt"
  22. "strings"
  23. "testing"
  24. "time"
  25. "github.com/google/go-cmp/cmp"
  26. "github.com/google/go-cmp/cmp/cmpopts"
  27. "google.golang.org/grpc/balancer"
  28. "google.golang.org/grpc/connectivity"
  29. "google.golang.org/grpc/internal/grpcsync"
  30. "google.golang.org/grpc/internal/grpctest"
  31. "google.golang.org/grpc/internal/testutils"
  32. "google.golang.org/grpc/resolver"
  33. "google.golang.org/grpc/serviceconfig"
  34. )
  35. const (
  36. defaultTestTimeout = 5 * time.Second
  37. defaultTestShortTimeout = 10 * time.Millisecond
  38. )
  39. type s struct {
  40. grpctest.Tester
  41. }
  42. func Test(t *testing.T) {
  43. grpctest.RunSubTests(t, s{})
  44. }
  45. func setup(t *testing.T) (*testutils.TestClientConn, *Balancer) {
  46. tcc := testutils.NewTestClientConn(t)
  47. return tcc, NewBalancer(tcc, balancer.BuildOptions{})
  48. }
  49. // TestSuccessfulFirstUpdate tests a basic scenario for the graceful switch load
  50. // balancer, where it is setup with a balancer which should populate the current
  51. // load balancer. Any ClientConn updates should then be forwarded to this
  52. // current load balancer.
  53. func (s) TestSuccessfulFirstUpdate(t *testing.T) {
  54. _, gsb := setup(t)
  55. if err := gsb.SwitchTo(mockBalancerBuilder1{}); err != nil {
  56. t.Fatalf("Balancer.SwitchTo failed with error: %v", err)
  57. }
  58. if gsb.balancerCurrent == nil {
  59. t.Fatal("current balancer not populated after a successful call to SwitchTo()")
  60. }
  61. // This will be used to update the graceful switch balancer. This update
  62. // should simply be forwarded down to the current load balancing policy.
  63. ccs := balancer.ClientConnState{
  64. BalancerConfig: mockBalancerConfig{},
  65. }
  66. // Updating ClientConnState should forward the update exactly as is to the
  67. // current balancer.
  68. if err := gsb.UpdateClientConnState(ccs); err != nil {
  69. t.Fatalf("Balancer.UpdateClientConnState(%v) failed: %v", ccs, err)
  70. }
  71. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  72. defer cancel()
  73. if err := gsb.balancerCurrent.Balancer.(*mockBalancer).waitForClientConnUpdate(ctx, ccs); err != nil {
  74. t.Fatal(err)
  75. }
  76. }
  77. // TestTwoBalancersSameType tests the scenario where there is a graceful switch
  78. // load balancer setup with a current and pending load balancer of the same
  79. // type. Any ClientConn update should be forwarded to the current lb if there is
  80. // a current lb and no pending lb, and the only the pending lb if the graceful
  81. // switch balancer contains both a current lb and a pending lb. The pending load
  82. // balancer should also swap into current whenever it updates with a
  83. // connectivity state other than CONNECTING.
  84. func (s) TestTwoBalancersSameType(t *testing.T) {
  85. tcc, gsb := setup(t)
  86. // This will be used to update the graceful switch balancer. This update
  87. // should simply be forwarded down to either the current or pending load
  88. // balancing policy.
  89. ccs := balancer.ClientConnState{
  90. BalancerConfig: mockBalancerConfig{},
  91. }
  92. gsb.SwitchTo(mockBalancerBuilder1{})
  93. gsb.UpdateClientConnState(ccs)
  94. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  95. defer cancel()
  96. if err := gsb.balancerCurrent.Balancer.(*mockBalancer).waitForClientConnUpdate(ctx, ccs); err != nil {
  97. t.Fatal(err)
  98. }
  99. // The current balancer reporting READY should cause this state
  100. // to be forwarded to the ClientConn.
  101. gsb.balancerCurrent.Balancer.(*mockBalancer).updateState(balancer.State{
  102. ConnectivityState: connectivity.Ready,
  103. Picker: &neverErrPicker{},
  104. })
  105. select {
  106. case <-ctx.Done():
  107. t.Fatalf("timeout while waiting for a UpdateState call on the ClientConn")
  108. case state := <-tcc.NewStateCh:
  109. if state != connectivity.Ready {
  110. t.Fatalf("current balancer reports connectivity state %v, want %v", state, connectivity.Ready)
  111. }
  112. }
  113. select {
  114. case <-ctx.Done():
  115. t.Fatalf("timeout while waiting for a UpdateState call on the ClientConn")
  116. case picker := <-tcc.NewPickerCh:
  117. // Should receive a never err picker.
  118. if _, err := picker.Pick(balancer.PickInfo{}); err != nil {
  119. t.Fatalf("ClientConn should have received a never err picker from an UpdateState call")
  120. }
  121. }
  122. // An explicit call to switchTo, even if the same type, should cause the
  123. // balancer to build a new balancer for pending.
  124. gsb.SwitchTo(mockBalancerBuilder1{})
  125. if gsb.balancerPending == nil {
  126. t.Fatal("pending balancer not populated after another call to SwitchTo()")
  127. }
  128. // A ClientConn update received should be forwarded to the new pending LB
  129. // policy, and not the current one.
  130. gsb.UpdateClientConnState(ccs)
  131. sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
  132. defer sCancel()
  133. if err := gsb.balancerCurrent.Balancer.(*mockBalancer).waitForClientConnUpdate(sCtx, ccs); err == nil {
  134. t.Fatal("current balancer received a ClientConn update when there is a pending balancer")
  135. }
  136. if err := gsb.balancerPending.Balancer.(*mockBalancer).waitForClientConnUpdate(ctx, ccs); err != nil {
  137. t.Fatal(err)
  138. }
  139. // If the pending load balancer reports that is CONNECTING, no update should
  140. // be sent to the ClientConn.
  141. gsb.balancerPending.Balancer.(*mockBalancer).updateState(balancer.State{
  142. ConnectivityState: connectivity.Connecting,
  143. })
  144. sCtx, sCancel = context.WithTimeout(context.Background(), defaultTestShortTimeout)
  145. defer sCancel()
  146. select {
  147. case <-tcc.NewStateCh:
  148. t.Fatal("balancerPending reporting CONNECTING should not forward up to the ClientConn")
  149. case <-sCtx.Done():
  150. }
  151. currBal := gsb.balancerCurrent.Balancer.(*mockBalancer)
  152. // If the pending load balancer reports a state other than CONNECTING, the
  153. // pending load balancer is logically warmed up, and the ClientConn should
  154. // be updated with the State and Picker to start using the new policy. The
  155. // pending load balancing policy should also be switched into the current
  156. // load balancer.
  157. gsb.balancerPending.Balancer.(*mockBalancer).updateState(balancer.State{
  158. ConnectivityState: connectivity.Ready,
  159. Picker: &neverErrPicker{},
  160. })
  161. select {
  162. case <-ctx.Done():
  163. t.Fatalf("timeout while waiting for a UpdateState call on the ClientConn")
  164. case state := <-tcc.NewStateCh:
  165. if state != connectivity.Ready {
  166. t.Fatalf("pending balancer reports connectivity state %v, want %v", state, connectivity.Ready)
  167. }
  168. }
  169. select {
  170. case <-ctx.Done():
  171. t.Fatalf("timeout while waiting for a UpdateState call on the ClientConn")
  172. case picker := <-tcc.NewPickerCh:
  173. // This picker should be the recent one sent from UpdateState(), a never
  174. // err picker, not the nil picker from two updateState() calls previous.
  175. if picker == nil {
  176. t.Fatalf("ClientConn should have received a never err picker, which is the most recent picker, from an UpdateState call")
  177. }
  178. if _, err := picker.Pick(balancer.PickInfo{}); err != nil {
  179. t.Fatalf("ClientConn should have received a never err picker, which is the most recent picker, from an UpdateState call")
  180. }
  181. }
  182. // The current balancer should be closed as a result of the swap.
  183. if err := currBal.waitForClose(ctx); err != nil {
  184. t.Fatal(err)
  185. }
  186. }
  187. // TestCurrentNotReadyPendingUpdate tests the scenario where there is a current
  188. // and pending load balancer setup in the graceful switch load balancer, and the
  189. // current LB is not in the connectivity state READY. Any update from the
  190. // pending load balancer should cause the graceful switch load balancer to swap
  191. // the pending into current, and update the ClientConn with the pending load
  192. // balancers state.
  193. func (s) TestCurrentNotReadyPendingUpdate(t *testing.T) {
  194. tcc, gsb := setup(t)
  195. gsb.SwitchTo(mockBalancerBuilder1{})
  196. gsb.SwitchTo(mockBalancerBuilder1{})
  197. if gsb.balancerPending == nil {
  198. t.Fatal("pending balancer not populated after another call to SwitchTo()")
  199. }
  200. currBal := gsb.balancerCurrent.Balancer.(*mockBalancer)
  201. // Due to the current load balancer not being in state READY, any update
  202. // from the pending load balancer should cause that update to be forwarded
  203. // to the ClientConn and also cause the pending load balancer to swap into
  204. // the current one.
  205. gsb.balancerPending.Balancer.(*mockBalancer).updateState(balancer.State{
  206. ConnectivityState: connectivity.Connecting,
  207. Picker: &neverErrPicker{},
  208. })
  209. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  210. defer cancel()
  211. select {
  212. case <-ctx.Done():
  213. t.Fatalf("timeout waiting for an UpdateState call on the ClientConn")
  214. case state := <-tcc.NewStateCh:
  215. if state != connectivity.Connecting {
  216. t.Fatalf("ClientConn received connectivity state %v, want %v (from pending)", state, connectivity.Connecting)
  217. }
  218. }
  219. select {
  220. case <-ctx.Done():
  221. t.Fatalf("timeout waiting for an UpdateState call on the ClientConn")
  222. case picker := <-tcc.NewPickerCh:
  223. // Should receive a never err picker.
  224. if _, err := picker.Pick(balancer.PickInfo{}); err != nil {
  225. t.Fatalf("ClientConn should have received a never err picker from an UpdateState call")
  226. }
  227. }
  228. // The current balancer should be closed as a result of the swap.
  229. if err := currBal.waitForClose(ctx); err != nil {
  230. t.Fatal(err)
  231. }
  232. }
  233. // TestCurrentLeavingReady tests the scenario where there is a current and
  234. // pending load balancer setup in the graceful switch load balancer, with the
  235. // current load balancer being in the state READY, and the current load balancer
  236. // then transitions into a state other than READY. This should cause the pending
  237. // load balancer to swap into the current load balancer, and the ClientConn to
  238. // be updated with the cached pending load balancing state. Also, once the
  239. // current is cleared from the graceful switch load balancer, any updates sent
  240. // should be intercepted and not forwarded to the ClientConn, as the balancer
  241. // has already been cleared.
  242. func (s) TestCurrentLeavingReady(t *testing.T) {
  243. tcc, gsb := setup(t)
  244. gsb.SwitchTo(mockBalancerBuilder1{})
  245. currBal := gsb.balancerCurrent.Balancer.(*mockBalancer)
  246. currBal.updateState(balancer.State{
  247. ConnectivityState: connectivity.Ready,
  248. })
  249. gsb.SwitchTo(mockBalancerBuilder2{})
  250. // Sends CONNECTING, shouldn't make it's way to ClientConn.
  251. gsb.balancerPending.Balancer.(*mockBalancer).updateState(balancer.State{
  252. ConnectivityState: connectivity.Connecting,
  253. Picker: &neverErrPicker{},
  254. })
  255. // The current balancer leaving READY should cause the pending balancer to
  256. // swap to the current balancer. This swap from current to pending should
  257. // also update the ClientConn with the pending balancers cached state and
  258. // picker.
  259. currBal.updateState(balancer.State{
  260. ConnectivityState: connectivity.Idle,
  261. })
  262. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  263. defer cancel()
  264. select {
  265. case <-ctx.Done():
  266. t.Fatalf("timeout while waiting for a UpdateState call on the ClientConn")
  267. case state := <-tcc.NewStateCh:
  268. if state != connectivity.Connecting {
  269. t.Fatalf("current balancer reports connectivity state %v, want %v", state, connectivity.Connecting)
  270. }
  271. }
  272. select {
  273. case <-ctx.Done():
  274. t.Fatalf("timeout while waiting for a UpdateState call on the ClientConn")
  275. case picker := <-tcc.NewPickerCh:
  276. // Should receive a never err picker cached from pending LB's updateState() call, which
  277. // was cached.
  278. if _, err := picker.Pick(balancer.PickInfo{}); err != nil {
  279. t.Fatalf("ClientConn should have received a never err picker, the cached picker, from an UpdateState call")
  280. }
  281. }
  282. // The current balancer should be closed as a result of the swap.
  283. if err := currBal.waitForClose(ctx); err != nil {
  284. t.Fatal(err)
  285. }
  286. // The current balancer is now cleared from the graceful switch load
  287. // balancer. Thus, any update from the old current should be intercepted by
  288. // the graceful switch load balancer and not forward up to the ClientConn.
  289. currBal.updateState(balancer.State{
  290. ConnectivityState: connectivity.Ready,
  291. Picker: &neverErrPicker{},
  292. })
  293. // This update should not be forwarded to the ClientConn.
  294. sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
  295. defer sCancel()
  296. select {
  297. case <-sCtx.Done():
  298. case <-tcc.NewStateCh:
  299. t.Fatal("UpdateState() from a cleared balancer should not make it's way to ClientConn")
  300. }
  301. if _, err := currBal.newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{}); err == nil {
  302. t.Fatal("newSubConn() from a cleared balancer should have returned an error")
  303. }
  304. // This newSubConn call should also not reach the ClientConn.
  305. sCtx, sCancel = context.WithTimeout(context.Background(), defaultTestShortTimeout)
  306. defer sCancel()
  307. select {
  308. case <-sCtx.Done():
  309. case <-tcc.NewSubConnCh:
  310. t.Fatal("newSubConn() from a cleared balancer should not make it's way to ClientConn")
  311. }
  312. }
  313. // TestBalancerSubconns tests the SubConn functionality of the graceful switch
  314. // load balancer. This tests the SubConn update flow in both directions, and
  315. // make sure updates end up at the correct component. Also, it tests that on an
  316. // UpdateSubConnState() call from the ClientConn, the graceful switch load
  317. // balancer forwards it to the correct child balancer.
  318. func (s) TestBalancerSubconns(t *testing.T) {
  319. tcc, gsb := setup(t)
  320. gsb.SwitchTo(mockBalancerBuilder1{})
  321. gsb.SwitchTo(mockBalancerBuilder2{})
  322. // A child balancer creating a new SubConn should eventually be forwarded to
  323. // the ClientConn held by the graceful switch load balancer.
  324. sc1, err := gsb.balancerCurrent.Balancer.(*mockBalancer).newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{})
  325. if err != nil {
  326. t.Fatalf("error constructing newSubConn in gsb: %v", err)
  327. }
  328. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  329. defer cancel()
  330. select {
  331. case <-ctx.Done():
  332. t.Fatalf("timeout while waiting for an NewSubConn call on the ClientConn")
  333. case sc := <-tcc.NewSubConnCh:
  334. if !cmp.Equal(sc1, sc, cmp.AllowUnexported(testutils.TestSubConn{})) {
  335. t.Fatalf("NewSubConn, want %v, got %v", sc1, sc)
  336. }
  337. }
  338. // The other child balancer creating a new SubConn should also be eventually
  339. // be forwarded to the ClientConn held by the graceful switch load balancer.
  340. sc2, err := gsb.balancerPending.Balancer.(*mockBalancer).newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{})
  341. if err != nil {
  342. t.Fatalf("error constructing newSubConn in gsb: %v", err)
  343. }
  344. select {
  345. case <-ctx.Done():
  346. t.Fatalf("timeout while waiting for an NewSubConn call on the ClientConn")
  347. case sc := <-tcc.NewSubConnCh:
  348. if !cmp.Equal(sc2, sc, cmp.AllowUnexported(testutils.TestSubConn{})) {
  349. t.Fatalf("NewSubConn, want %v, got %v", sc2, sc)
  350. }
  351. }
  352. scState := balancer.SubConnState{ConnectivityState: connectivity.Ready}
  353. // Updating the SubConnState for sc1 should cause the graceful switch
  354. // balancer to forward the Update to balancerCurrent for sc1, as that is the
  355. // balancer that created this SubConn.
  356. gsb.UpdateSubConnState(sc1, scState)
  357. // This update should get forwarded to balancerCurrent, as that is the LB
  358. // that created this SubConn.
  359. if err := gsb.balancerCurrent.Balancer.(*mockBalancer).waitForSubConnUpdate(ctx, subConnWithState{sc: sc1, state: scState}); err != nil {
  360. t.Fatal(err)
  361. }
  362. // This update should not get forwarded to balancerPending, as that is not
  363. // the LB that created this SubConn.
  364. sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
  365. defer sCancel()
  366. if err := gsb.balancerPending.Balancer.(*mockBalancer).waitForSubConnUpdate(sCtx, subConnWithState{sc: sc1, state: scState}); err == nil {
  367. t.Fatalf("balancerPending should not have received a subconn update for sc1")
  368. }
  369. // Updating the SubConnState for sc2 should cause the graceful switch
  370. // balancer to forward the Update to balancerPending for sc2, as that is the
  371. // balancer that created this SubConn.
  372. gsb.UpdateSubConnState(sc2, scState)
  373. // This update should get forwarded to balancerPending, as that is the LB
  374. // that created this SubConn.
  375. if err := gsb.balancerPending.Balancer.(*mockBalancer).waitForSubConnUpdate(ctx, subConnWithState{sc: sc2, state: scState}); err != nil {
  376. t.Fatal(err)
  377. }
  378. // This update should not get forwarded to balancerCurrent, as that is not
  379. // the LB that created this SubConn.
  380. sCtx, sCancel = context.WithTimeout(context.Background(), defaultTestShortTimeout)
  381. defer sCancel()
  382. if err := gsb.balancerCurrent.Balancer.(*mockBalancer).waitForSubConnUpdate(sCtx, subConnWithState{sc: sc2, state: scState}); err == nil {
  383. t.Fatalf("balancerCurrent should not have received a subconn update for sc2")
  384. }
  385. // Updating the addresses for both SubConns and removing both SubConns
  386. // should get forwarded to the ClientConn.
  387. // Updating the addresses for sc1 should get forwarded to the ClientConn.
  388. gsb.balancerCurrent.Balancer.(*mockBalancer).updateAddresses(sc1, []resolver.Address{})
  389. select {
  390. case <-ctx.Done():
  391. t.Fatalf("timeout while waiting for an UpdateAddresses call on the ClientConn")
  392. case <-tcc.UpdateAddressesAddrsCh:
  393. }
  394. // Updating the addresses for sc2 should also get forwarded to the ClientConn.
  395. gsb.balancerPending.Balancer.(*mockBalancer).updateAddresses(sc2, []resolver.Address{})
  396. select {
  397. case <-ctx.Done():
  398. t.Fatalf("timeout while waiting for an UpdateAddresses call on the ClientConn")
  399. case <-tcc.UpdateAddressesAddrsCh:
  400. }
  401. // balancerCurrent removing sc1 should get forwarded to the ClientConn.
  402. gsb.balancerCurrent.Balancer.(*mockBalancer).removeSubConn(sc1)
  403. select {
  404. case <-ctx.Done():
  405. t.Fatalf("timeout while waiting for an UpdateAddresses call on the ClientConn")
  406. case sc := <-tcc.RemoveSubConnCh:
  407. if !cmp.Equal(sc1, sc, cmp.AllowUnexported(testutils.TestSubConn{})) {
  408. t.Fatalf("RemoveSubConn, want %v, got %v", sc1, sc)
  409. }
  410. }
  411. // balancerPending removing sc2 should get forwarded to the ClientConn.
  412. gsb.balancerPending.Balancer.(*mockBalancer).removeSubConn(sc2)
  413. select {
  414. case <-ctx.Done():
  415. t.Fatalf("timeout while waiting for an UpdateAddresses call on the ClientConn")
  416. case sc := <-tcc.RemoveSubConnCh:
  417. if !cmp.Equal(sc2, sc, cmp.AllowUnexported(testutils.TestSubConn{})) {
  418. t.Fatalf("RemoveSubConn, want %v, got %v", sc2, sc)
  419. }
  420. }
  421. }
  422. // TestBalancerClose tests the graceful switch balancer's Close() functionality.
  423. // From the Close() call, the graceful switch balancer should remove any created
  424. // Subconns and Close() the current and pending load balancers. This Close()
  425. // call should also cause any other events (calls to entrance functions) to be
  426. // no-ops.
  427. func (s) TestBalancerClose(t *testing.T) {
  428. // Setup gsb balancer with current, pending, and one created SubConn on both
  429. // current and pending.
  430. tcc, gsb := setup(t)
  431. gsb.SwitchTo(mockBalancerBuilder1{})
  432. gsb.SwitchTo(mockBalancerBuilder2{})
  433. sc1, err := gsb.balancerCurrent.Balancer.(*mockBalancer).newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{}) // Will eventually get back a SubConn with an identifying property id 1
  434. if err != nil {
  435. t.Fatalf("error constructing newSubConn in gsb: %v", err)
  436. }
  437. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  438. defer cancel()
  439. select {
  440. case <-ctx.Done():
  441. t.Fatalf("timeout while waiting for an NewSubConn call on the ClientConn")
  442. case <-tcc.NewSubConnCh:
  443. }
  444. sc2, err := gsb.balancerPending.Balancer.(*mockBalancer).newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{}) // Will eventually get back a SubConn with an identifying property id 2
  445. if err != nil {
  446. t.Fatalf("error constructing newSubConn in gsb: %v", err)
  447. }
  448. select {
  449. case <-ctx.Done():
  450. t.Fatalf("timeout while waiting for an NewSubConn call on the ClientConn")
  451. case <-tcc.NewSubConnCh:
  452. }
  453. currBal := gsb.balancerCurrent.Balancer.(*mockBalancer)
  454. pendBal := gsb.balancerPending.Balancer.(*mockBalancer)
  455. // Closing the graceful switch load balancer should lead to removing any
  456. // created SubConns, and closing both the current and pending load balancer.
  457. gsb.Close()
  458. // The order of SubConns the graceful switch load balancer tells the Client
  459. // Conn to remove is non deterministic, as it is stored in a map. However,
  460. // the first SubConn removed should be either sc1 or sc2.
  461. select {
  462. case <-ctx.Done():
  463. t.Fatalf("timeout while waiting for an UpdateAddresses call on the ClientConn")
  464. case sc := <-tcc.RemoveSubConnCh:
  465. if !cmp.Equal(sc1, sc, cmp.AllowUnexported(testutils.TestSubConn{})) {
  466. if !cmp.Equal(sc2, sc, cmp.AllowUnexported(testutils.TestSubConn{})) {
  467. t.Fatalf("RemoveSubConn, want either %v or %v, got %v", sc1, sc2, sc)
  468. }
  469. }
  470. }
  471. // The graceful switch load balancer should then tell the ClientConn to
  472. // remove the other SubConn.
  473. select {
  474. case <-ctx.Done():
  475. t.Fatalf("timeout while waiting for an UpdateAddresses call on the ClientConn")
  476. case sc := <-tcc.RemoveSubConnCh:
  477. if !cmp.Equal(sc1, sc, cmp.AllowUnexported(testutils.TestSubConn{})) {
  478. if !cmp.Equal(sc2, sc, cmp.AllowUnexported(testutils.TestSubConn{})) {
  479. t.Fatalf("RemoveSubConn, want either %v or %v, got %v", sc1, sc2, sc)
  480. }
  481. }
  482. }
  483. // The current balancer should get closed as a result of the graceful switch balancer being closed.
  484. if err := currBal.waitForClose(ctx); err != nil {
  485. t.Fatal(err)
  486. }
  487. // The pending balancer should also get closed as a result of the graceful switch balancer being closed.
  488. if err := pendBal.waitForClose(ctx); err != nil {
  489. t.Fatal(err)
  490. }
  491. // Once the graceful switch load balancer has been closed, any entrance
  492. // function should be a no-op and return errBalancerClosed if the function
  493. // returns an error.
  494. // SwitchTo() should return an error due to the graceful switch load
  495. // balancer having been closed already.
  496. if err := gsb.SwitchTo(mockBalancerBuilder1{}); err != errBalancerClosed {
  497. t.Fatalf("gsb.SwitchTo(%v) returned error %v, want %v", mockBalancerBuilder1{}, err, errBalancerClosed)
  498. }
  499. // UpdateClientConnState() should return an error due to the graceful switch
  500. // load balancer having been closed already.
  501. ccs := balancer.ClientConnState{
  502. BalancerConfig: mockBalancerConfig{},
  503. }
  504. if err := gsb.UpdateClientConnState(ccs); err != errBalancerClosed {
  505. t.Fatalf("gsb.UpdateCLientConnState(%v) returned error %v, want %v", ccs, err, errBalancerClosed)
  506. }
  507. // After the graceful switch load balancer has been closed, any resolver error
  508. // shouldn't forward to either balancer, as the resolver error is a no-op
  509. // and also even if not, the balancers should have been cleared from the
  510. // graceful switch load balancer.
  511. gsb.ResolverError(balancer.ErrBadResolverState)
  512. sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
  513. defer sCancel()
  514. if err := currBal.waitForResolverError(sCtx, balancer.ErrBadResolverState); !strings.Contains(err.Error(), sCtx.Err().Error()) {
  515. t.Fatal("the current balancer should not have received the resolver error after close")
  516. }
  517. sCtx, sCancel = context.WithTimeout(context.Background(), defaultTestShortTimeout)
  518. defer sCancel()
  519. if err := pendBal.waitForResolverError(sCtx, balancer.ErrBadResolverState); !strings.Contains(err.Error(), sCtx.Err().Error()) {
  520. t.Fatal("the pending balancer should not have received the resolver error after close")
  521. }
  522. }
  523. // TestResolverError tests the functionality of a Resolver Error. If there is a
  524. // current balancer, but no pending, the error should be forwarded to the
  525. // current balancer. If there is both a current and pending balancer, the error
  526. // should be forwarded to only the pending balancer.
  527. func (s) TestResolverError(t *testing.T) {
  528. _, gsb := setup(t)
  529. gsb.SwitchTo(mockBalancerBuilder1{})
  530. currBal := gsb.balancerCurrent.Balancer.(*mockBalancer)
  531. // If there is only a current balancer present, the resolver error should be
  532. // forwarded to the current balancer.
  533. gsb.ResolverError(balancer.ErrBadResolverState)
  534. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  535. defer cancel()
  536. if err := currBal.waitForResolverError(ctx, balancer.ErrBadResolverState); err != nil {
  537. t.Fatal(err)
  538. }
  539. gsb.SwitchTo(mockBalancerBuilder1{})
  540. // If there is a pending balancer present, then a resolver error should be
  541. // forwarded to only the pending balancer, not the current.
  542. pendBal := gsb.balancerPending.Balancer.(*mockBalancer)
  543. gsb.ResolverError(balancer.ErrBadResolverState)
  544. // The Resolver Error should not be forwarded to the current load balancer.
  545. sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
  546. defer sCancel()
  547. if err := currBal.waitForResolverError(sCtx, balancer.ErrBadResolverState); !strings.Contains(err.Error(), sCtx.Err().Error()) {
  548. t.Fatal("the current balancer should not have received the resolver error after close")
  549. }
  550. // The Resolver Error should be forwarded to the pending load balancer.
  551. if err := pendBal.waitForResolverError(ctx, balancer.ErrBadResolverState); err != nil {
  552. t.Fatal(err)
  553. }
  554. }
  555. // TestPendingReplacedByAnotherPending tests the scenario where a graceful
  556. // switch balancer has a current and pending load balancer, and receives a
  557. // SwitchTo() call, which then replaces the pending. This should cause the
  558. // graceful switch balancer to clear pending state, close old pending SubConns,
  559. // and Close() the pending balancer being replaced.
  560. func (s) TestPendingReplacedByAnotherPending(t *testing.T) {
  561. tcc, gsb := setup(t)
  562. gsb.SwitchTo(mockBalancerBuilder1{})
  563. currBal := gsb.balancerCurrent.Balancer.(*mockBalancer)
  564. currBal.updateState(balancer.State{
  565. ConnectivityState: connectivity.Ready,
  566. })
  567. // Populate pending with a SwitchTo() call.
  568. gsb.SwitchTo(mockBalancerBuilder2{})
  569. pendBal := gsb.balancerPending.Balancer.(*mockBalancer)
  570. sc1, err := pendBal.newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{})
  571. if err != nil {
  572. t.Fatalf("error constructing newSubConn in gsb: %v", err)
  573. }
  574. // This picker never returns an error, which can help this this test verify
  575. // whether this cached state will get cleared on a new pending balancer
  576. // (will replace it with a picker that always errors).
  577. pendBal.updateState(balancer.State{
  578. ConnectivityState: connectivity.Connecting,
  579. Picker: &neverErrPicker{},
  580. })
  581. // Replace pending with a SwitchTo() call.
  582. gsb.SwitchTo(mockBalancerBuilder2{})
  583. // The pending balancer being replaced should cause the graceful switch
  584. // balancer to Remove() any created SubConns for the old pending balancer
  585. // and also Close() the old pending balancer.
  586. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  587. defer cancel()
  588. select {
  589. case <-ctx.Done():
  590. t.Fatalf("timeout while waiting for a RemoveSubConn call on the ClientConn")
  591. case sc := <-tcc.RemoveSubConnCh:
  592. if !cmp.Equal(sc1, sc, cmp.AllowUnexported(testutils.TestSubConn{})) {
  593. t.Fatalf("RemoveSubConn, want %v, got %v", sc1, sc)
  594. }
  595. }
  596. if err := pendBal.waitForClose(ctx); err != nil {
  597. t.Fatal(err)
  598. }
  599. // Switching the current out of READY should cause the pending LB to swap
  600. // into current, causing the graceful switch balancer to update the
  601. // ClientConn with the cached pending state. Since the new pending hasn't
  602. // sent an Update, the default state with connectivity state CONNECTING and
  603. // an errPicker should be sent to the ClientConn.
  604. currBal.updateState(balancer.State{
  605. ConnectivityState: connectivity.Idle,
  606. })
  607. // The update should contain a default connectivity state CONNECTING for the
  608. // state of the new pending LB policy.
  609. select {
  610. case <-ctx.Done():
  611. t.Fatalf("timeout while waiting for an UpdateState() call on the ClientConn")
  612. case state := <-tcc.NewStateCh:
  613. if state != connectivity.Connecting {
  614. t.Fatalf("UpdateState(), want connectivity state %v, got %v", connectivity.Connecting, state)
  615. }
  616. }
  617. // The update should contain a default picker ErrPicker in the picker sent
  618. // for the state of the new pending LB policy.
  619. select {
  620. case <-ctx.Done():
  621. t.Fatalf("timeout while waiting for an UpdateState() call on the ClientConn")
  622. case picker := <-tcc.NewPickerCh:
  623. if _, err := picker.Pick(balancer.PickInfo{}); err != balancer.ErrNoSubConnAvailable {
  624. t.Fatalf("ClientConn should have received a never err picker from an UpdateState call")
  625. }
  626. }
  627. }
  628. // Picker which never errors here for test purposes (can fill up tests further up with this)
  629. type neverErrPicker struct{}
  630. func (p *neverErrPicker) Pick(info balancer.PickInfo) (balancer.PickResult, error) {
  631. return balancer.PickResult{}, nil
  632. }
  633. // TestUpdateSubConnStateRace tests the race condition when the graceful switch
  634. // load balancer receives a SubConnUpdate concurrently with an UpdateState()
  635. // call, which can cause the balancer to forward the update to to be closed and
  636. // cleared. The balancer API guarantees to never call any method the balancer
  637. // after a Close() call, and the test verifies that doesn't happen within the
  638. // graceful switch load balancer.
  639. func (s) TestUpdateSubConnStateRace(t *testing.T) {
  640. tcc, gsb := setup(t)
  641. gsb.SwitchTo(verifyBalancerBuilder{})
  642. gsb.SwitchTo(mockBalancerBuilder1{})
  643. currBal := gsb.balancerCurrent.Balancer.(*verifyBalancer)
  644. currBal.t = t
  645. pendBal := gsb.balancerPending.Balancer.(*mockBalancer)
  646. sc, err := currBal.newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{})
  647. if err != nil {
  648. t.Fatalf("error constructing newSubConn in gsb: %v", err)
  649. }
  650. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  651. defer cancel()
  652. select {
  653. case <-ctx.Done():
  654. t.Fatalf("timeout while waiting for an NewSubConn call on the ClientConn")
  655. case <-tcc.NewSubConnCh:
  656. }
  657. // Spawn a goroutine that constantly calls UpdateSubConn for the current
  658. // balancer, which will get deleted in this testing goroutine.
  659. finished := make(chan struct{})
  660. go func() {
  661. for {
  662. select {
  663. case <-finished:
  664. return
  665. default:
  666. }
  667. gsb.UpdateSubConnState(sc, balancer.SubConnState{
  668. ConnectivityState: connectivity.Ready,
  669. })
  670. }
  671. }()
  672. time.Sleep(time.Millisecond)
  673. // This UpdateState call causes current to be closed/cleared.
  674. pendBal.updateState(balancer.State{
  675. ConnectivityState: connectivity.Ready,
  676. })
  677. // From this, either one of two things happen. Either the graceful switch
  678. // load balancer doesn't Close() the current balancer before it forwards the
  679. // SubConn update to the child, and the call gets forwarded down to the
  680. // current balancer, or it can Close() the current balancer in between
  681. // reading the balancer pointer and writing to it, and in that case the old
  682. // current balancer should not be updated, as the balancer has already been
  683. // closed and the balancer API guarantees it.
  684. close(finished)
  685. }
  686. // TestInlineCallbackInBuild tests the scenario where a balancer calls back into
  687. // the balancer.ClientConn API inline from it's build function.
  688. func (s) TestInlineCallbackInBuild(t *testing.T) {
  689. tcc, gsb := setup(t)
  690. // This build call should cause all of the inline updates to forward to the
  691. // ClientConn.
  692. gsb.SwitchTo(buildCallbackBalancerBuilder{})
  693. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  694. defer cancel()
  695. select {
  696. case <-ctx.Done():
  697. t.Fatalf("timeout while waiting for an UpdateState() call on the ClientConn")
  698. case <-tcc.NewStateCh:
  699. }
  700. select {
  701. case <-ctx.Done():
  702. t.Fatalf("timeout while waiting for an NewSubConn() call on the ClientConn")
  703. case <-tcc.NewSubConnCh:
  704. }
  705. select {
  706. case <-ctx.Done():
  707. t.Fatalf("timeout while waiting for an UpdateAddresses() call on the ClientConn")
  708. case <-tcc.UpdateAddressesAddrsCh:
  709. }
  710. select {
  711. case <-ctx.Done():
  712. t.Fatalf("timeout while waiting for an RemoveSubConn() call on the ClientConn")
  713. case <-tcc.RemoveSubConnCh:
  714. }
  715. oldCurrent := gsb.balancerCurrent.Balancer.(*buildCallbackBal)
  716. // Since the callback reports a state READY, this new inline balancer should
  717. // be swapped to the current.
  718. gsb.SwitchTo(buildCallbackBalancerBuilder{})
  719. select {
  720. case <-ctx.Done():
  721. t.Fatalf("timeout while waiting for an UpdateState() call on the ClientConn")
  722. case <-tcc.NewStateCh:
  723. }
  724. select {
  725. case <-ctx.Done():
  726. t.Fatalf("timeout while waiting for an NewSubConn() call on the ClientConn")
  727. case <-tcc.NewSubConnCh:
  728. }
  729. select {
  730. case <-ctx.Done():
  731. t.Fatalf("timeout while waiting for an UpdateAddresses() call on the ClientConn")
  732. case <-tcc.UpdateAddressesAddrsCh:
  733. }
  734. select {
  735. case <-ctx.Done():
  736. t.Fatalf("timeout while waiting for an RemoveSubConn() call on the ClientConn")
  737. case <-tcc.RemoveSubConnCh:
  738. }
  739. // The current balancer should be closed as a result of the swap.
  740. if err := oldCurrent.waitForClose(ctx); err != nil {
  741. t.Fatalf("error waiting for balancer close: %v", err)
  742. }
  743. // The old balancer should be deprecated and any calls from it should be a no-op.
  744. oldCurrent.newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{})
  745. sCtx, sCancel := context.WithTimeout(context.Background(), defaultTestShortTimeout)
  746. defer sCancel()
  747. select {
  748. case <-tcc.NewSubConnCh:
  749. t.Fatal("Deprecated LB calling NewSubConn() should not forward up to the ClientConn")
  750. case <-sCtx.Done():
  751. }
  752. }
  753. // TestExitIdle tests the ExitIdle operation on the Graceful Switch Balancer for
  754. // both possible codepaths, one where the child implements ExitIdler interface
  755. // and one where the child doesn't implement ExitIdler interface.
  756. func (s) TestExitIdle(t *testing.T) {
  757. _, gsb := setup(t)
  758. // switch to a balancer that implements ExitIdle{} (will populate current).
  759. gsb.SwitchTo(mockBalancerBuilder1{})
  760. currBal := gsb.balancerCurrent.Balancer.(*mockBalancer)
  761. ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
  762. defer cancel()
  763. // exitIdle on the Graceful Switch Balancer should get forwarded to the
  764. // current child as it implements exitIdle.
  765. gsb.ExitIdle()
  766. if err := currBal.waitForExitIdle(ctx); err != nil {
  767. t.Fatal(err)
  768. }
  769. // switch to a balancer that doesn't implement ExitIdle{} (will populate
  770. // pending).
  771. gsb.SwitchTo(verifyBalancerBuilder{})
  772. // call exitIdle concurrently with newSubConn to make sure there is not a
  773. // data race.
  774. done := make(chan struct{})
  775. go func() {
  776. gsb.ExitIdle()
  777. close(done)
  778. }()
  779. pendBal := gsb.balancerPending.Balancer.(*verifyBalancer)
  780. for i := 0; i < 10; i++ {
  781. pendBal.newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{})
  782. }
  783. <-done
  784. }
  785. const balancerName1 = "mock_balancer_1"
  786. const balancerName2 = "mock_balancer_2"
  787. const verifyBalName = "verifyNoSubConnUpdateAfterCloseBalancer"
  788. const buildCallbackBalName = "callbackInBuildBalancer"
  789. type mockBalancerBuilder1 struct{}
  790. func (mockBalancerBuilder1) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
  791. return &mockBalancer{
  792. ccsCh: testutils.NewChannel(),
  793. scStateCh: testutils.NewChannel(),
  794. resolverErrCh: testutils.NewChannel(),
  795. closeCh: testutils.NewChannel(),
  796. exitIdleCh: testutils.NewChannel(),
  797. cc: cc,
  798. }
  799. }
  800. func (mockBalancerBuilder1) Name() string {
  801. return balancerName1
  802. }
  803. type mockBalancerConfig struct {
  804. serviceconfig.LoadBalancingConfig
  805. }
  806. // mockBalancer is a fake balancer used to verify different actions from
  807. // the gracefulswitch. It contains a bunch of channels to signal different events
  808. // to the test.
  809. type mockBalancer struct {
  810. // ccsCh is a channel used to signal the receipt of a ClientConn update.
  811. ccsCh *testutils.Channel
  812. // scStateCh is a channel used to signal the receipt of a SubConn update.
  813. scStateCh *testutils.Channel
  814. // resolverErrCh is a channel used to signal a resolver error.
  815. resolverErrCh *testutils.Channel
  816. // closeCh is a channel used to signal the closing of this balancer.
  817. closeCh *testutils.Channel
  818. // exitIdleCh is a channel used to signal the receipt of an ExitIdle call.
  819. exitIdleCh *testutils.Channel
  820. // Hold onto ClientConn wrapper to communicate with it
  821. cc balancer.ClientConn
  822. }
  823. type subConnWithState struct {
  824. sc balancer.SubConn
  825. state balancer.SubConnState
  826. }
  827. func (mb1 *mockBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
  828. // Need to verify this call...use a channel?...all of these will need verification
  829. mb1.ccsCh.Send(ccs)
  830. return nil
  831. }
  832. func (mb1 *mockBalancer) ResolverError(err error) {
  833. mb1.resolverErrCh.Send(err)
  834. }
  835. func (mb1 *mockBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
  836. mb1.scStateCh.Send(subConnWithState{sc: sc, state: state})
  837. }
  838. func (mb1 *mockBalancer) Close() {
  839. mb1.closeCh.Send(struct{}{})
  840. }
  841. func (mb1 *mockBalancer) ExitIdle() {
  842. mb1.exitIdleCh.Send(struct{}{})
  843. }
  844. // waitForClientConnUpdate verifies if the mockBalancer receives the
  845. // provided ClientConnState within a reasonable amount of time.
  846. func (mb1 *mockBalancer) waitForClientConnUpdate(ctx context.Context, wantCCS balancer.ClientConnState) error {
  847. ccs, err := mb1.ccsCh.Receive(ctx)
  848. if err != nil {
  849. return fmt.Errorf("error waiting for ClientConnUpdate: %v", err)
  850. }
  851. gotCCS := ccs.(balancer.ClientConnState)
  852. if diff := cmp.Diff(gotCCS, wantCCS, cmpopts.IgnoreFields(resolver.State{}, "Attributes")); diff != "" {
  853. return fmt.Errorf("error in ClientConnUpdate: received unexpected ClientConnState, diff (-got +want): %v", diff)
  854. }
  855. return nil
  856. }
  857. // waitForSubConnUpdate verifies if the mockBalancer receives the provided
  858. // SubConn update before the context expires.
  859. func (mb1 *mockBalancer) waitForSubConnUpdate(ctx context.Context, wantSCS subConnWithState) error {
  860. scs, err := mb1.scStateCh.Receive(ctx)
  861. if err != nil {
  862. return fmt.Errorf("error waiting for SubConnUpdate: %v", err)
  863. }
  864. gotSCS := scs.(subConnWithState)
  865. if !cmp.Equal(gotSCS, wantSCS, cmp.AllowUnexported(subConnWithState{}, testutils.TestSubConn{})) {
  866. return fmt.Errorf("error in SubConnUpdate: received SubConnState: %+v, want %+v", gotSCS, wantSCS)
  867. }
  868. return nil
  869. }
  870. // waitForResolverError verifies if the mockBalancer receives the provided
  871. // resolver error before the context expires.
  872. func (mb1 *mockBalancer) waitForResolverError(ctx context.Context, wantErr error) error {
  873. gotErr, err := mb1.resolverErrCh.Receive(ctx)
  874. if err != nil {
  875. return fmt.Errorf("error waiting for resolver error: %v", err)
  876. }
  877. if gotErr != wantErr {
  878. return fmt.Errorf("received resolver error: %v, want %v", gotErr, wantErr)
  879. }
  880. return nil
  881. }
  882. // waitForClose verifies that the mockBalancer is closed before the context
  883. // expires.
  884. func (mb1 *mockBalancer) waitForClose(ctx context.Context) error {
  885. if _, err := mb1.closeCh.Receive(ctx); err != nil {
  886. return fmt.Errorf("error waiting for Close(): %v", err)
  887. }
  888. return nil
  889. }
  890. // waitForExitIdle verifies that ExitIdle gets called on the mockBalancer before
  891. // the context expires.
  892. func (mb1 *mockBalancer) waitForExitIdle(ctx context.Context) error {
  893. if _, err := mb1.exitIdleCh.Receive(ctx); err != nil {
  894. return fmt.Errorf("error waiting for ExitIdle(): %v", err)
  895. }
  896. return nil
  897. }
  898. func (mb1 *mockBalancer) updateState(state balancer.State) {
  899. mb1.cc.UpdateState(state)
  900. }
  901. func (mb1 *mockBalancer) newSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
  902. return mb1.cc.NewSubConn(addrs, opts)
  903. }
  904. func (mb1 *mockBalancer) updateAddresses(sc balancer.SubConn, addrs []resolver.Address) {
  905. mb1.cc.UpdateAddresses(sc, addrs)
  906. }
  907. func (mb1 *mockBalancer) removeSubConn(sc balancer.SubConn) {
  908. mb1.cc.RemoveSubConn(sc)
  909. }
  910. type mockBalancerBuilder2 struct{}
  911. func (mockBalancerBuilder2) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
  912. return &mockBalancer{
  913. ccsCh: testutils.NewChannel(),
  914. scStateCh: testutils.NewChannel(),
  915. resolverErrCh: testutils.NewChannel(),
  916. closeCh: testutils.NewChannel(),
  917. cc: cc,
  918. }
  919. }
  920. func (mockBalancerBuilder2) Name() string {
  921. return balancerName2
  922. }
  923. type verifyBalancerBuilder struct{}
  924. func (verifyBalancerBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
  925. return &verifyBalancer{
  926. closed: grpcsync.NewEvent(),
  927. cc: cc,
  928. }
  929. }
  930. func (verifyBalancerBuilder) Name() string {
  931. return verifyBalName
  932. }
  933. // verifyBalancer is a balancer that verifies that after a Close() call, an
  934. // updateSubConnState() call never happens.
  935. type verifyBalancer struct {
  936. closed *grpcsync.Event
  937. // Hold onto the ClientConn wrapper to communicate with it.
  938. cc balancer.ClientConn
  939. // To fail the test if UpdateSubConnState gets called after Close().
  940. t *testing.T
  941. }
  942. func (vb *verifyBalancer) UpdateClientConnState(ccs balancer.ClientConnState) error {
  943. return nil
  944. }
  945. func (vb *verifyBalancer) ResolverError(err error) {}
  946. func (vb *verifyBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {
  947. if vb.closed.HasFired() {
  948. vb.t.Fatal("UpdateSubConnState was called after Close(), which breaks the balancer API")
  949. }
  950. }
  951. func (vb *verifyBalancer) Close() {
  952. vb.closed.Fire()
  953. }
  954. func (vb *verifyBalancer) newSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
  955. return vb.cc.NewSubConn(addrs, opts)
  956. }
  957. type buildCallbackBalancerBuilder struct{}
  958. func (buildCallbackBalancerBuilder) Build(cc balancer.ClientConn, opts balancer.BuildOptions) balancer.Balancer {
  959. b := &buildCallbackBal{
  960. cc: cc,
  961. closeCh: testutils.NewChannel(),
  962. }
  963. b.updateState(balancer.State{
  964. ConnectivityState: connectivity.Connecting,
  965. })
  966. sc, err := b.newSubConn([]resolver.Address{}, balancer.NewSubConnOptions{})
  967. if err != nil {
  968. return nil
  969. }
  970. b.updateAddresses(sc, []resolver.Address{})
  971. b.removeSubConn(sc)
  972. return b
  973. }
  974. func (buildCallbackBalancerBuilder) Name() string {
  975. return buildCallbackBalName
  976. }
  977. type buildCallbackBal struct {
  978. // Hold onto the ClientConn wrapper to communicate with it.
  979. cc balancer.ClientConn
  980. // closeCh is a channel used to signal the closing of this balancer.
  981. closeCh *testutils.Channel
  982. }
  983. func (bcb *buildCallbackBal) UpdateClientConnState(ccs balancer.ClientConnState) error {
  984. return nil
  985. }
  986. func (bcb *buildCallbackBal) ResolverError(err error) {}
  987. func (bcb *buildCallbackBal) UpdateSubConnState(sc balancer.SubConn, state balancer.SubConnState) {}
  988. func (bcb *buildCallbackBal) Close() {
  989. bcb.closeCh.Send(struct{}{})
  990. }
  991. func (bcb *buildCallbackBal) updateState(state balancer.State) {
  992. bcb.cc.UpdateState(state)
  993. }
  994. func (bcb *buildCallbackBal) newSubConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (balancer.SubConn, error) {
  995. return bcb.cc.NewSubConn(addrs, opts)
  996. }
  997. func (bcb *buildCallbackBal) updateAddresses(sc balancer.SubConn, addrs []resolver.Address) {
  998. bcb.cc.UpdateAddresses(sc, addrs)
  999. }
  1000. func (bcb *buildCallbackBal) removeSubConn(sc balancer.SubConn) {
  1001. bcb.cc.RemoveSubConn(sc)
  1002. }
  1003. // waitForClose verifies that the mockBalancer is closed before the context
  1004. // expires.
  1005. func (bcb *buildCallbackBal) waitForClose(ctx context.Context) error {
  1006. if _, err := bcb.closeCh.Receive(ctx); err != nil {
  1007. return err
  1008. }
  1009. return nil
  1010. }