gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/grpc/reflection/serverreflection_test.go (about) 1 /* 2 * 3 * Copyright 2016 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 reflection 20 21 import ( 22 "context" 23 "fmt" 24 "gitee.com/zhaochuninhefei/gmgo/grpc/credentials/insecure" 25 "net" 26 "reflect" 27 "sort" 28 "testing" 29 "time" 30 31 "gitee.com/zhaochuninhefei/gmgo/grpc" 32 "gitee.com/zhaochuninhefei/gmgo/grpc/internal/grpctest" 33 rpb "gitee.com/zhaochuninhefei/gmgo/grpc/reflection/grpc_reflection_v1alpha" 34 pb "gitee.com/zhaochuninhefei/gmgo/grpc/reflection/grpc_testing" 35 pbv3 "gitee.com/zhaochuninhefei/gmgo/grpc/reflection/grpc_testingv3" 36 "github.com/golang/protobuf/proto" 37 dpb "github.com/golang/protobuf/protoc-gen-go/descriptor" 38 ) 39 40 //goland:noinspection GoUnusedGlobalVariable 41 var ( 42 s = &serverReflectionServer{} 43 // fileDescriptor of each test proto file. 44 fdTest *dpb.FileDescriptorProto 45 fdTestv3 *dpb.FileDescriptorProto 46 fdProto2 *dpb.FileDescriptorProto 47 fdProto2Ext *dpb.FileDescriptorProto 48 fdProto2Ext2 *dpb.FileDescriptorProto 49 // fileDescriptor marshalled. 50 fdTestByte []byte 51 fdTestv3Byte []byte 52 fdProto2Byte []byte 53 fdProto2ExtByte []byte 54 fdProto2Ext2Byte []byte 55 ) 56 57 const defaultTestTimeout = 10 * time.Second 58 59 type x struct { 60 grpctest.Tester 61 } 62 63 func Test(t *testing.T) { 64 grpctest.RunSubTests(t, x{}) 65 } 66 67 func loadFileDesc(filename string) (*dpb.FileDescriptorProto, []byte) { 68 //goland:noinspection GoDeprecation 69 enc := proto.FileDescriptor(filename) 70 if enc == nil { 71 panic(fmt.Sprintf("failed to find fd for file: %v", filename)) 72 } 73 fd, err := decodeFileDesc(enc) 74 if err != nil { 75 panic(fmt.Sprintf("failed to decode enc: %v", err)) 76 } 77 b, err := proto.Marshal(fd) 78 if err != nil { 79 panic(fmt.Sprintf("failed to marshal fd: %v", err)) 80 } 81 return fd, b 82 } 83 84 func init() { 85 fdTest, fdTestByte = loadFileDesc("reflection/grpc_testing/test.proto") 86 fdTestv3, fdTestv3Byte = loadFileDesc("testv3.proto") 87 fdProto2, fdProto2Byte = loadFileDesc("reflection/grpc_testing/proto2.proto") 88 fdProto2Ext, fdProto2ExtByte = loadFileDesc("reflection/grpc_testing/proto2_ext.proto") 89 fdProto2Ext2, fdProto2Ext2Byte = loadFileDesc("reflection/grpc_testing/proto2_ext2.proto") 90 } 91 92 func (x) TestFileDescForType(t *testing.T) { 93 for _, test := range []struct { 94 st reflect.Type 95 wantFd *dpb.FileDescriptorProto 96 }{ 97 {reflect.TypeOf(pb.SearchResponse_Result{}), fdTest}, 98 {reflect.TypeOf(pb.ToBeExtended{}), fdProto2}, 99 } { 100 fd, err := s.fileDescForType(test.st) 101 if err != nil || !proto.Equal(fd, test.wantFd) { 102 t.Errorf("fileDescForType(%q) = %q, %v, want %q, <nil>", test.st, fd, err, test.wantFd) 103 } 104 } 105 } 106 107 func (x) TestTypeForName(t *testing.T) { 108 for _, test := range []struct { 109 name string 110 want reflect.Type 111 }{ 112 {"grpc.testing.SearchResponse", reflect.TypeOf(pb.SearchResponse{})}, 113 } { 114 r, err := typeForName(test.name) 115 if err != nil || r != test.want { 116 t.Errorf("typeForName(%q) = %q, %v, want %q, <nil>", test.name, r, err, test.want) 117 } 118 } 119 } 120 121 func (x) TestTypeForNameNotFound(t *testing.T) { 122 for _, test := range []string{ 123 "grpc.testing.not_exiting", 124 } { 125 _, err := typeForName(test) 126 if err == nil { 127 t.Errorf("typeForName(%q) = _, %v, want _, <non-nil>", test, err) 128 } 129 } 130 } 131 132 func (x) TestFileDescContainingExtension(t *testing.T) { 133 for _, test := range []struct { 134 st reflect.Type 135 extNum int32 136 want *dpb.FileDescriptorProto 137 }{ 138 {reflect.TypeOf(pb.ToBeExtended{}), 13, fdProto2Ext}, 139 {reflect.TypeOf(pb.ToBeExtended{}), 17, fdProto2Ext}, 140 {reflect.TypeOf(pb.ToBeExtended{}), 19, fdProto2Ext}, 141 {reflect.TypeOf(pb.ToBeExtended{}), 23, fdProto2Ext2}, 142 {reflect.TypeOf(pb.ToBeExtended{}), 29, fdProto2Ext2}, 143 } { 144 fd, err := fileDescContainingExtension(test.st, test.extNum) 145 if err != nil || !proto.Equal(fd, test.want) { 146 t.Errorf("fileDescContainingExtension(%q) = %q, %v, want %q, <nil>", test.st, fd, err, test.want) 147 } 148 } 149 } 150 151 // intArray is used to sort []int32 152 type intArray []int32 153 154 func (s intArray) Len() int { return len(s) } 155 func (s intArray) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 156 func (s intArray) Less(i, j int) bool { return s[i] < s[j] } 157 158 func (x) TestAllExtensionNumbersForType(t *testing.T) { 159 for _, test := range []struct { 160 st reflect.Type 161 want []int32 162 }{ 163 {reflect.TypeOf(pb.ToBeExtended{}), []int32{13, 17, 19, 23, 29}}, 164 } { 165 r, err := s.allExtensionNumbersForType(test.st) 166 sort.Sort(intArray(r)) 167 if err != nil || !reflect.DeepEqual(r, test.want) { 168 t.Errorf("allExtensionNumbersForType(%q) = %v, %v, want %v, <nil>", test.st, r, err, test.want) 169 } 170 } 171 } 172 173 // Do end2end tests. 174 175 type server struct { 176 pb.UnimplementedSearchServiceServer 177 } 178 179 //goland:noinspection GoUnusedParameter 180 func (s *server) Search(ctx context.Context, in *pb.SearchRequest) (*pb.SearchResponse, error) { 181 return &pb.SearchResponse{}, nil 182 } 183 184 //goland:noinspection GoUnusedParameter 185 func (s *server) StreamingSearch(stream pb.SearchService_StreamingSearchServer) error { 186 return nil 187 } 188 189 type serverV3 struct{} 190 191 //goland:noinspection GoUnusedParameter 192 func (s *serverV3) Search(ctx context.Context, in *pbv3.SearchRequestV3) (*pbv3.SearchResponseV3, error) { 193 return &pbv3.SearchResponseV3{}, nil 194 } 195 196 //goland:noinspection GoUnusedParameter 197 func (s *serverV3) StreamingSearch(stream pbv3.SearchServiceV3_StreamingSearchServer) error { 198 return nil 199 } 200 201 func (x) TestReflectionEnd2end(t *testing.T) { 202 // Start server. 203 lis, err := net.Listen("tcp", "localhost:0") 204 if err != nil { 205 t.Fatalf("failed to listen: %v", err) 206 } 207 s := grpc.NewServer() 208 pb.RegisterSearchServiceServer(s, &server{}) 209 pbv3.RegisterSearchServiceV3Server(s, &serverV3{}) 210 // Register reflection service on s. 211 Register(s) 212 go func() { 213 _ = s.Serve(lis) 214 }() 215 216 // Create client. 217 // grpc.WithInsecure() is deprecated, use WithTransportCredentials and insecure.NewCredentials() instead. 218 //conn, err := grpc.Dial(lis.Addr().String(), grpc.WithInsecure()) 219 conn, err := grpc.Dial(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) 220 if err != nil { 221 t.Fatalf("cannot connect to server: %v", err) 222 } 223 defer func(conn *grpc.ClientConn) { 224 _ = conn.Close() 225 }(conn) 226 227 c := rpb.NewServerReflectionClient(conn) 228 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 229 defer cancel() 230 stream, err := c.ServerReflectionInfo(ctx, grpc.WaitForReady(true)) 231 if err != nil { 232 t.Fatalf("cannot get ServerReflectionInfo: %v", err) 233 } 234 235 testFileByFilenameTransitiveClosure(t, stream, true) 236 testFileByFilenameTransitiveClosure(t, stream, false) 237 testFileByFilename(t, stream) 238 testFileByFilenameError(t, stream) 239 testFileContainingSymbol(t, stream) 240 testFileContainingSymbolError(t, stream) 241 testFileContainingExtension(t, stream) 242 testFileContainingExtensionError(t, stream) 243 testAllExtensionNumbersOfType(t, stream) 244 testAllExtensionNumbersOfTypeError(t, stream) 245 testListServices(t, stream) 246 247 s.Stop() 248 } 249 250 func testFileByFilenameTransitiveClosure(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient, expectClosure bool) { 251 filename := "reflection/grpc_testing/proto2_ext2.proto" 252 if err := stream.Send(&rpb.ServerReflectionRequest{ 253 MessageRequest: &rpb.ServerReflectionRequest_FileByFilename{ 254 FileByFilename: filename, 255 }, 256 }); err != nil { 257 t.Fatalf("failed to send request: %v", err) 258 } 259 r, err := stream.Recv() 260 if err != nil { 261 // io.EOF is not ok. 262 t.Fatalf("failed to recv response: %v", err) 263 } 264 switch r.MessageResponse.(type) { 265 case *rpb.ServerReflectionResponse_FileDescriptorResponse: 266 if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[0], fdProto2Ext2Byte) { 267 t.Errorf("FileByFilename(%v)\nreceived: %q,\nwant: %q", filename, r.GetFileDescriptorResponse().FileDescriptorProto[0], fdProto2Ext2Byte) 268 } 269 if expectClosure { 270 if len(r.GetFileDescriptorResponse().FileDescriptorProto) != 2 { 271 t.Errorf("FileByFilename(%v) returned %v file descriptors, expected 2", filename, len(r.GetFileDescriptorResponse().FileDescriptorProto)) 272 } else if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[1], fdProto2Byte) { 273 t.Errorf("FileByFilename(%v)\nreceived: %q,\nwant: %q", filename, r.GetFileDescriptorResponse().FileDescriptorProto[1], fdProto2Byte) 274 } 275 } else if len(r.GetFileDescriptorResponse().FileDescriptorProto) != 1 { 276 t.Errorf("FileByFilename(%v) returned %v file descriptors, expected 1", filename, len(r.GetFileDescriptorResponse().FileDescriptorProto)) 277 } 278 default: 279 t.Errorf("FileByFilename(%v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", filename, r.MessageResponse) 280 } 281 } 282 283 func testFileByFilename(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient) { 284 for _, test := range []struct { 285 filename string 286 want []byte 287 }{ 288 {"reflection/grpc_testing/test.proto", fdTestByte}, 289 {"reflection/grpc_testing/proto2.proto", fdProto2Byte}, 290 {"reflection/grpc_testing/proto2_ext.proto", fdProto2ExtByte}, 291 } { 292 if err := stream.Send(&rpb.ServerReflectionRequest{ 293 MessageRequest: &rpb.ServerReflectionRequest_FileByFilename{ 294 FileByFilename: test.filename, 295 }, 296 }); err != nil { 297 t.Fatalf("failed to send request: %v", err) 298 } 299 r, err := stream.Recv() 300 if err != nil { 301 // io.EOF is not ok. 302 t.Fatalf("failed to recv response: %v", err) 303 } 304 305 switch r.MessageResponse.(type) { 306 case *rpb.ServerReflectionResponse_FileDescriptorResponse: 307 if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) { 308 t.Errorf("FileByFilename(%v)\nreceived: %q,\nwant: %q", test.filename, r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) 309 } 310 default: 311 t.Errorf("FileByFilename(%v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", test.filename, r.MessageResponse) 312 } 313 } 314 } 315 316 func testFileByFilenameError(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient) { 317 for _, test := range []string{ 318 "test.poto", 319 "proo2.proto", 320 "proto2_et.proto", 321 } { 322 if err := stream.Send(&rpb.ServerReflectionRequest{ 323 MessageRequest: &rpb.ServerReflectionRequest_FileByFilename{ 324 FileByFilename: test, 325 }, 326 }); err != nil { 327 t.Fatalf("failed to send request: %v", err) 328 } 329 r, err := stream.Recv() 330 if err != nil { 331 // io.EOF is not ok. 332 t.Fatalf("failed to recv response: %v", err) 333 } 334 335 switch r.MessageResponse.(type) { 336 case *rpb.ServerReflectionResponse_ErrorResponse: 337 default: 338 t.Errorf("FileByFilename(%v) = %v, want type <ServerReflectionResponse_ErrorResponse>", test, r.MessageResponse) 339 } 340 } 341 } 342 343 func testFileContainingSymbol(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient) { 344 for _, test := range []struct { 345 symbol string 346 want []byte 347 }{ 348 {"grpc.testing.SearchService", fdTestByte}, 349 {"grpc.testing.SearchService.Search", fdTestByte}, 350 {"grpc.testing.SearchService.StreamingSearch", fdTestByte}, 351 {"grpc.testing.SearchResponse", fdTestByte}, 352 {"grpc.testing.ToBeExtended", fdProto2Byte}, 353 // Test support package v3. 354 {"grpc.testingv3.SearchServiceV3", fdTestv3Byte}, 355 {"grpc.testingv3.SearchServiceV3.Search", fdTestv3Byte}, 356 {"grpc.testingv3.SearchServiceV3.StreamingSearch", fdTestv3Byte}, 357 {"grpc.testingv3.SearchResponseV3", fdTestv3Byte}, 358 // search for field, oneof, enum, and enum value symbols, too 359 {"grpc.testingv3.SearchResponseV3.Result.snippets", fdTestv3Byte}, 360 {"grpc.testingv3.SearchResponseV3.Result.Value.val", fdTestv3Byte}, 361 {"grpc.testingv3.SearchResponseV3.Result.Value.str", fdTestv3Byte}, 362 {"grpc.testingv3.SearchResponseV3.State", fdTestv3Byte}, 363 {"grpc.testingv3.SearchResponseV3.State.FRESH", fdTestv3Byte}, 364 } { 365 if err := stream.Send(&rpb.ServerReflectionRequest{ 366 MessageRequest: &rpb.ServerReflectionRequest_FileContainingSymbol{ 367 FileContainingSymbol: test.symbol, 368 }, 369 }); err != nil { 370 t.Fatalf("failed to send request: %v", err) 371 } 372 r, err := stream.Recv() 373 if err != nil { 374 // io.EOF is not ok. 375 t.Fatalf("failed to recv response: %v", err) 376 } 377 378 switch r.MessageResponse.(type) { 379 case *rpb.ServerReflectionResponse_FileDescriptorResponse: 380 if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) { 381 t.Errorf("FileContainingSymbol(%v)\nreceived: %q,\nwant: %q", test.symbol, r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) 382 } 383 default: 384 t.Errorf("FileContainingSymbol(%v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", test.symbol, r.MessageResponse) 385 } 386 } 387 } 388 389 func testFileContainingSymbolError(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient) { 390 for _, test := range []string{ 391 "grpc.testing.SerchService", 392 "grpc.testing.SearchService.SearchE", 393 "grpc.tesing.SearchResponse", 394 "gpc.testing.ToBeExtended", 395 } { 396 if err := stream.Send(&rpb.ServerReflectionRequest{ 397 MessageRequest: &rpb.ServerReflectionRequest_FileContainingSymbol{ 398 FileContainingSymbol: test, 399 }, 400 }); err != nil { 401 t.Fatalf("failed to send request: %v", err) 402 } 403 r, err := stream.Recv() 404 if err != nil { 405 // io.EOF is not ok. 406 t.Fatalf("failed to recv response: %v", err) 407 } 408 409 switch r.MessageResponse.(type) { 410 case *rpb.ServerReflectionResponse_ErrorResponse: 411 default: 412 t.Errorf("FileContainingSymbol(%v) = %v, want type <ServerReflectionResponse_ErrorResponse>", test, r.MessageResponse) 413 } 414 } 415 } 416 417 func testFileContainingExtension(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient) { 418 for _, test := range []struct { 419 typeName string 420 extNum int32 421 want []byte 422 }{ 423 {"grpc.testing.ToBeExtended", 13, fdProto2ExtByte}, 424 {"grpc.testing.ToBeExtended", 17, fdProto2ExtByte}, 425 {"grpc.testing.ToBeExtended", 19, fdProto2ExtByte}, 426 {"grpc.testing.ToBeExtended", 23, fdProto2Ext2Byte}, 427 {"grpc.testing.ToBeExtended", 29, fdProto2Ext2Byte}, 428 } { 429 if err := stream.Send(&rpb.ServerReflectionRequest{ 430 MessageRequest: &rpb.ServerReflectionRequest_FileContainingExtension{ 431 FileContainingExtension: &rpb.ExtensionRequest{ 432 ContainingType: test.typeName, 433 ExtensionNumber: test.extNum, 434 }, 435 }, 436 }); err != nil { 437 t.Fatalf("failed to send request: %v", err) 438 } 439 r, err := stream.Recv() 440 if err != nil { 441 // io.EOF is not ok. 442 t.Fatalf("failed to recv response: %v", err) 443 } 444 445 switch r.MessageResponse.(type) { 446 case *rpb.ServerReflectionResponse_FileDescriptorResponse: 447 if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) { 448 t.Errorf("FileContainingExtension(%v, %v)\nreceived: %q,\nwant: %q", test.typeName, test.extNum, r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) 449 } 450 default: 451 t.Errorf("FileContainingExtension(%v, %v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", test.typeName, test.extNum, r.MessageResponse) 452 } 453 } 454 } 455 456 func testFileContainingExtensionError(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient) { 457 for _, test := range []struct { 458 typeName string 459 extNum int32 460 }{ 461 {"grpc.testing.ToBExtended", 17}, 462 {"grpc.testing.ToBeExtended", 15}, 463 } { 464 if err := stream.Send(&rpb.ServerReflectionRequest{ 465 MessageRequest: &rpb.ServerReflectionRequest_FileContainingExtension{ 466 FileContainingExtension: &rpb.ExtensionRequest{ 467 ContainingType: test.typeName, 468 ExtensionNumber: test.extNum, 469 }, 470 }, 471 }); err != nil { 472 t.Fatalf("failed to send request: %v", err) 473 } 474 r, err := stream.Recv() 475 if err != nil { 476 // io.EOF is not ok. 477 t.Fatalf("failed to recv response: %v", err) 478 } 479 480 switch r.MessageResponse.(type) { 481 case *rpb.ServerReflectionResponse_ErrorResponse: 482 default: 483 t.Errorf("FileContainingExtension(%v, %v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", test.typeName, test.extNum, r.MessageResponse) 484 } 485 } 486 } 487 488 func testAllExtensionNumbersOfType(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient) { 489 for _, test := range []struct { 490 typeName string 491 want []int32 492 }{ 493 {"grpc.testing.ToBeExtended", []int32{13, 17, 19, 23, 29}}, 494 } { 495 if err := stream.Send(&rpb.ServerReflectionRequest{ 496 MessageRequest: &rpb.ServerReflectionRequest_AllExtensionNumbersOfType{ 497 AllExtensionNumbersOfType: test.typeName, 498 }, 499 }); err != nil { 500 t.Fatalf("failed to send request: %v", err) 501 } 502 r, err := stream.Recv() 503 if err != nil { 504 // io.EOF is not ok. 505 t.Fatalf("failed to recv response: %v", err) 506 } 507 508 switch r.MessageResponse.(type) { 509 case *rpb.ServerReflectionResponse_AllExtensionNumbersResponse: 510 extNum := r.GetAllExtensionNumbersResponse().ExtensionNumber 511 sort.Sort(intArray(extNum)) 512 if r.GetAllExtensionNumbersResponse().BaseTypeName != test.typeName || 513 !reflect.DeepEqual(extNum, test.want) { 514 t.Errorf("AllExtensionNumbersOfType(%v)\nreceived: %v,\nwant: {%q %v}", r.GetAllExtensionNumbersResponse(), test.typeName, test.typeName, test.want) 515 } 516 default: 517 t.Errorf("AllExtensionNumbersOfType(%v) = %v, want type <ServerReflectionResponse_AllExtensionNumbersResponse>", test.typeName, r.MessageResponse) 518 } 519 } 520 } 521 522 func testAllExtensionNumbersOfTypeError(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient) { 523 for _, test := range []string{ 524 "grpc.testing.ToBeExtendedE", 525 } { 526 if err := stream.Send(&rpb.ServerReflectionRequest{ 527 MessageRequest: &rpb.ServerReflectionRequest_AllExtensionNumbersOfType{ 528 AllExtensionNumbersOfType: test, 529 }, 530 }); err != nil { 531 t.Fatalf("failed to send request: %v", err) 532 } 533 r, err := stream.Recv() 534 if err != nil { 535 // io.EOF is not ok. 536 t.Fatalf("failed to recv response: %v", err) 537 } 538 539 switch r.MessageResponse.(type) { 540 case *rpb.ServerReflectionResponse_ErrorResponse: 541 default: 542 t.Errorf("AllExtensionNumbersOfType(%v) = %v, want type <ServerReflectionResponse_ErrorResponse>", test, r.MessageResponse) 543 } 544 } 545 } 546 547 func testListServices(t *testing.T, stream rpb.ServerReflection_ServerReflectionInfoClient) { 548 if err := stream.Send(&rpb.ServerReflectionRequest{ 549 MessageRequest: &rpb.ServerReflectionRequest_ListServices{}, 550 }); err != nil { 551 t.Fatalf("failed to send request: %v", err) 552 } 553 r, err := stream.Recv() 554 if err != nil { 555 // io.EOF is not ok. 556 t.Fatalf("failed to recv response: %v", err) 557 } 558 559 switch r.MessageResponse.(type) { 560 case *rpb.ServerReflectionResponse_ListServicesResponse: 561 services := r.GetListServicesResponse().Service 562 want := []string{ 563 "grpc.testingv3.SearchServiceV3", 564 "grpc.testing.SearchService", 565 "grpc.reflection.v1alpha.ServerReflection", 566 } 567 // Compare service names in response with want. 568 if len(services) != len(want) { 569 t.Errorf("= %v, want service names: %v", services, want) 570 } 571 m := make(map[string]int) 572 for _, e := range services { 573 m[e.Name]++ 574 } 575 for _, e := range want { 576 if m[e] > 0 { 577 m[e]-- 578 continue 579 } 580 t.Errorf("ListService\nreceived: %v,\nwant: %q", services, want) 581 } 582 default: 583 t.Errorf("ListServices = %v, want type <ServerReflectionResponse_ListServicesResponse>", r.MessageResponse) 584 } 585 }