gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/grpc/pickfirst_test.go (about) 1 /* 2 * 3 * Copyright 2017 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 19 package grpc 20 21 import ( 22 "context" 23 "gitee.com/zhaochuninhefei/gmgo/grpc/credentials/insecure" 24 "math" 25 "sync" 26 "testing" 27 "time" 28 29 "gitee.com/zhaochuninhefei/gmgo/grpc/codes" 30 "gitee.com/zhaochuninhefei/gmgo/grpc/resolver" 31 "gitee.com/zhaochuninhefei/gmgo/grpc/resolver/manual" 32 "gitee.com/zhaochuninhefei/gmgo/grpc/status" 33 ) 34 35 func errorDesc(err error) string { 36 if s, ok := status.FromError(err); ok { 37 return s.Message() 38 } 39 return err.Error() 40 } 41 42 func (s) TestOneBackendPickfirst(t *testing.T) { 43 r := manual.NewBuilderWithScheme("whatever") 44 45 numServers := 1 46 servers, scleanup := startServers(t, numServers, math.MaxInt32) 47 defer scleanup() 48 49 cc, err := Dial(r.Scheme()+":///test.server", 50 // WithInsecure() is deprecated, use WithTransportCredentials and insecure.NewCredentials() instead. 51 //WithInsecure(), 52 WithTransportCredentials(insecure.NewCredentials()), 53 WithResolvers(r), 54 // WithCodec() is deprecated, use WithDefaultCallOptions(ForceCodec(_)) instead. 55 //WithCodec(testCodec{})) 56 WithDefaultCallOptions(ForceCodec(testCodec{}))) 57 if err != nil { 58 t.Fatalf("failed to dial: %v", err) 59 } 60 defer func(cc *ClientConn) { 61 _ = cc.Close() 62 }(cc) 63 // The first RPC should fail because there's no address. 64 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) 65 defer cancel() 66 req := "port" 67 var reply string 68 if err := cc.Invoke(ctx, "/foo/bar", &req, &reply); err == nil || status.Code(err) != codes.DeadlineExceeded { 69 t.Fatalf("EmptyCall() = _, %v, want _, DeadlineExceeded", err) 70 } 71 72 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[0].addr}}}) 73 // The second RPC should succeed. 74 for i := 0; i < 1000; i++ { 75 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err != nil && errorDesc(err) == servers[0].port { 76 return 77 } 78 time.Sleep(time.Millisecond) 79 } 80 t.Fatalf("EmptyCall() = _, %v, want _, %v", err, servers[0].port) 81 } 82 83 func (s) TestBackendsPickfirst(t *testing.T) { 84 r := manual.NewBuilderWithScheme("whatever") 85 86 numServers := 2 87 servers, scleanup := startServers(t, numServers, math.MaxInt32) 88 defer scleanup() 89 90 // WithInsecure() is deprecated, use WithTransportCredentials and insecure.NewCredentials() instead. 91 // WithCodec() is deprecated, use WithDefaultCallOptions(ForceCodec(_)) instead. 92 //cc, err := Dial(r.Scheme()+":///test.server", WithInsecure(), WithResolvers(r), WithCodec(testCodec{})) 93 cc, err := Dial(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDefaultCallOptions(ForceCodec(testCodec{}))) 94 if err != nil { 95 t.Fatalf("failed to dial: %v", err) 96 } 97 defer func(cc *ClientConn) { 98 _ = cc.Close() 99 }(cc) 100 // The first RPC should fail because there's no address. 101 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) 102 defer cancel() 103 req := "port" 104 var reply string 105 if err := cc.Invoke(ctx, "/foo/bar", &req, &reply); err == nil || status.Code(err) != codes.DeadlineExceeded { 106 t.Fatalf("EmptyCall() = _, %v, want _, DeadlineExceeded", err) 107 } 108 109 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[0].addr}, {Addr: servers[1].addr}}}) 110 // The second RPC should succeed with the first server. 111 for i := 0; i < 1000; i++ { 112 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err != nil && errorDesc(err) == servers[0].port { 113 return 114 } 115 time.Sleep(time.Millisecond) 116 } 117 t.Fatalf("EmptyCall() = _, %v, want _, %v", err, servers[0].port) 118 } 119 120 func (s) TestNewAddressWhileBlockingPickfirst(t *testing.T) { 121 r := manual.NewBuilderWithScheme("whatever") 122 123 numServers := 1 124 servers, scleanup := startServers(t, numServers, math.MaxInt32) 125 defer scleanup() 126 127 // WithInsecure() is deprecated, use WithTransportCredentials and insecure.NewCredentials() instead. 128 // WithCodec() is deprecated, use WithDefaultCallOptions(ForceCodec(_)) instead. 129 cc, err := Dial(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDefaultCallOptions(ForceCodec(testCodec{}))) 130 if err != nil { 131 t.Fatalf("failed to dial: %v", err) 132 } 133 defer func(cc *ClientConn) { 134 _ = cc.Close() 135 }(cc) 136 // The first RPC should fail because there's no address. 137 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) 138 defer cancel() 139 req := "port" 140 var reply string 141 if err := cc.Invoke(ctx, "/foo/bar", &req, &reply); err == nil || status.Code(err) != codes.DeadlineExceeded { 142 t.Fatalf("EmptyCall() = _, %v, want _, DeadlineExceeded", err) 143 } 144 145 var wg sync.WaitGroup 146 for i := 0; i < 3; i++ { 147 wg.Add(1) 148 go func() { 149 defer wg.Done() 150 // This RPC blocks until NewAddress is called. 151 _ = cc.Invoke(context.Background(), "/foo/bar", &req, &reply) 152 }() 153 } 154 time.Sleep(50 * time.Millisecond) 155 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[0].addr}}}) 156 wg.Wait() 157 } 158 159 func (s) TestCloseWithPendingRPCPickfirst(t *testing.T) { 160 r := manual.NewBuilderWithScheme("whatever") 161 162 numServers := 1 163 _, scleanup := startServers(t, numServers, math.MaxInt32) 164 defer scleanup() 165 166 // WithInsecure() is deprecated, use WithTransportCredentials and insecure.NewCredentials() instead. 167 // WithCodec() is deprecated, use WithDefaultCallOptions(ForceCodec(_)) instead. 168 cc, err := Dial(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDefaultCallOptions(ForceCodec(testCodec{}))) 169 if err != nil { 170 t.Fatalf("failed to dial: %v", err) 171 } 172 defer func(cc *ClientConn) { 173 _ = cc.Close() 174 }(cc) 175 // The first RPC should fail because there's no address. 176 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) 177 defer cancel() 178 req := "port" 179 var reply string 180 if err := cc.Invoke(ctx, "/foo/bar", &req, &reply); err == nil || status.Code(err) != codes.DeadlineExceeded { 181 t.Fatalf("EmptyCall() = _, %v, want _, DeadlineExceeded", err) 182 } 183 184 var wg sync.WaitGroup 185 for i := 0; i < 3; i++ { 186 wg.Add(1) 187 go func() { 188 defer wg.Done() 189 // This RPC blocks until NewAddress is called. 190 _ = cc.Invoke(context.Background(), "/foo/bar", &req, &reply) 191 }() 192 } 193 time.Sleep(50 * time.Millisecond) 194 _ = cc.Close() 195 wg.Wait() 196 } 197 198 func (s) TestOneServerDownPickfirst(t *testing.T) { 199 r := manual.NewBuilderWithScheme("whatever") 200 201 numServers := 2 202 servers, scleanup := startServers(t, numServers, math.MaxInt32) 203 defer scleanup() 204 205 // WithInsecure() is deprecated, use WithTransportCredentials and insecure.NewCredentials() instead. 206 // WithCodec() is deprecated, use WithDefaultCallOptions(ForceCodec(_)) instead. 207 cc, err := Dial(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDefaultCallOptions(ForceCodec(testCodec{}))) 208 if err != nil { 209 t.Fatalf("failed to dial: %v", err) 210 } 211 defer func(cc *ClientConn) { 212 _ = cc.Close() 213 }(cc) 214 // The first RPC should fail because there's no address. 215 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) 216 defer cancel() 217 req := "port" 218 var reply string 219 if err := cc.Invoke(ctx, "/foo/bar", &req, &reply); err == nil || status.Code(err) != codes.DeadlineExceeded { 220 t.Fatalf("EmptyCall() = _, %v, want _, DeadlineExceeded", err) 221 } 222 223 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[0].addr}, {Addr: servers[1].addr}}}) 224 // The second RPC should succeed with the first server. 225 for i := 0; i < 1000; i++ { 226 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err != nil && errorDesc(err) == servers[0].port { 227 break 228 } 229 time.Sleep(time.Millisecond) 230 } 231 232 servers[0].stop() 233 for i := 0; i < 1000; i++ { 234 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err != nil && errorDesc(err) == servers[1].port { 235 return 236 } 237 time.Sleep(time.Millisecond) 238 } 239 t.Fatalf("EmptyCall() = _, %v, want _, %v", err, servers[0].port) 240 } 241 242 func (s) TestAllServersDownPickfirst(t *testing.T) { 243 r := manual.NewBuilderWithScheme("whatever") 244 245 numServers := 2 246 servers, scleanup := startServers(t, numServers, math.MaxInt32) 247 defer scleanup() 248 249 // WithInsecure() is deprecated, use WithTransportCredentials and insecure.NewCredentials() instead. 250 // WithCodec() is deprecated, use WithDefaultCallOptions(ForceCodec(_)) instead. 251 cc, err := Dial(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDefaultCallOptions(ForceCodec(testCodec{}))) 252 if err != nil { 253 t.Fatalf("failed to dial: %v", err) 254 } 255 defer func(cc *ClientConn) { 256 _ = cc.Close() 257 }(cc) 258 // The first RPC should fail because there's no address. 259 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) 260 defer cancel() 261 req := "port" 262 var reply string 263 if err := cc.Invoke(ctx, "/foo/bar", &req, &reply); err == nil || status.Code(err) != codes.DeadlineExceeded { 264 t.Fatalf("EmptyCall() = _, %v, want _, DeadlineExceeded", err) 265 } 266 267 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[0].addr}, {Addr: servers[1].addr}}}) 268 // The second RPC should succeed with the first server. 269 for i := 0; i < 1000; i++ { 270 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err != nil && errorDesc(err) == servers[0].port { 271 break 272 } 273 time.Sleep(time.Millisecond) 274 } 275 276 for i := 0; i < numServers; i++ { 277 servers[i].stop() 278 } 279 for i := 0; i < 1000; i++ { 280 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); status.Code(err) == codes.Unavailable { 281 return 282 } 283 time.Sleep(time.Millisecond) 284 } 285 t.Fatalf("EmptyCall() = _, %v, want _, error with code unavailable", err) 286 } 287 288 func (s) TestAddressesRemovedPickfirst(t *testing.T) { 289 r := manual.NewBuilderWithScheme("whatever") 290 291 numServers := 3 292 servers, scleanup := startServers(t, numServers, math.MaxInt32) 293 defer scleanup() 294 295 // WithInsecure() is deprecated, use WithTransportCredentials and insecure.NewCredentials() instead. 296 // WithCodec() is deprecated, use WithDefaultCallOptions(ForceCodec(_)) instead. 297 cc, err := Dial(r.Scheme()+":///test.server", WithTransportCredentials(insecure.NewCredentials()), WithResolvers(r), WithDefaultCallOptions(ForceCodec(testCodec{}))) 298 if err != nil { 299 t.Fatalf("failed to dial: %v", err) 300 } 301 defer func(cc *ClientConn) { 302 _ = cc.Close() 303 }(cc) 304 // The first RPC should fail because there's no address. 305 ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond) 306 defer cancel() 307 req := "port" 308 var reply string 309 if err := cc.Invoke(ctx, "/foo/bar", &req, &reply); err == nil || status.Code(err) != codes.DeadlineExceeded { 310 t.Fatalf("EmptyCall() = _, %v, want _, DeadlineExceeded", err) 311 } 312 313 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[0].addr}, {Addr: servers[1].addr}, {Addr: servers[2].addr}}}) 314 for i := 0; i < 1000; i++ { 315 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err != nil && errorDesc(err) == servers[0].port { 316 break 317 } 318 time.Sleep(time.Millisecond) 319 } 320 for i := 0; i < 20; i++ { 321 if err := cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err == nil || errorDesc(err) != servers[0].port { 322 t.Fatalf("Index %d: Invoke(_, _, _, _, _) = %v, want %s", 0, err, servers[0].port) 323 } 324 time.Sleep(10 * time.Millisecond) 325 } 326 327 // Remove server[0]. 328 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[1].addr}, {Addr: servers[2].addr}}}) 329 for i := 0; i < 1000; i++ { 330 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err != nil && errorDesc(err) == servers[1].port { 331 break 332 } 333 time.Sleep(time.Millisecond) 334 } 335 for i := 0; i < 20; i++ { 336 if err := cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err == nil || errorDesc(err) != servers[1].port { 337 t.Fatalf("Index %d: Invoke(_, _, _, _, _) = %v, want %s", 1, err, servers[1].port) 338 } 339 time.Sleep(10 * time.Millisecond) 340 } 341 342 // Append server[0], nothing should change. 343 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[1].addr}, {Addr: servers[2].addr}, {Addr: servers[0].addr}}}) 344 for i := 0; i < 20; i++ { 345 if err := cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err == nil || errorDesc(err) != servers[1].port { 346 t.Fatalf("Index %d: Invoke(_, _, _, _, _) = %v, want %s", 1, err, servers[1].port) 347 } 348 time.Sleep(10 * time.Millisecond) 349 } 350 351 // Remove server[1]. 352 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[2].addr}, {Addr: servers[0].addr}}}) 353 for i := 0; i < 1000; i++ { 354 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err != nil && errorDesc(err) == servers[2].port { 355 break 356 } 357 time.Sleep(time.Millisecond) 358 } 359 for i := 0; i < 20; i++ { 360 if err := cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err == nil || errorDesc(err) != servers[2].port { 361 t.Fatalf("Index %d: Invoke(_, _, _, _, _) = %v, want %s", 2, err, servers[2].port) 362 } 363 time.Sleep(10 * time.Millisecond) 364 } 365 366 // Remove server[2]. 367 r.UpdateState(resolver.State{Addresses: []resolver.Address{{Addr: servers[0].addr}}}) 368 for i := 0; i < 1000; i++ { 369 if err = cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err != nil && errorDesc(err) == servers[0].port { 370 break 371 } 372 time.Sleep(time.Millisecond) 373 } 374 for i := 0; i < 20; i++ { 375 if err := cc.Invoke(context.Background(), "/foo/bar", &req, &reply); err == nil || errorDesc(err) != servers[0].port { 376 t.Fatalf("Index %d: Invoke(_, _, _, _, _) = %v, want %s", 0, err, servers[0].port) 377 } 378 time.Sleep(10 * time.Millisecond) 379 } 380 }