google.golang.org/grpc@v1.62.1/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 "net" 25 "reflect" 26 "sort" 27 "testing" 28 "time" 29 30 "google.golang.org/grpc" 31 "google.golang.org/grpc/credentials/insecure" 32 "google.golang.org/grpc/internal/grpctest" 33 "google.golang.org/protobuf/proto" 34 "google.golang.org/protobuf/reflect/protodesc" 35 "google.golang.org/protobuf/reflect/protoreflect" 36 "google.golang.org/protobuf/reflect/protoregistry" 37 "google.golang.org/protobuf/types/descriptorpb" 38 "google.golang.org/protobuf/types/dynamicpb" 39 40 v1reflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1" 41 v1reflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1" 42 v1alphareflectiongrpc "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" 43 v1alphareflectionpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha" 44 pb "google.golang.org/grpc/reflection/grpc_testing" 45 pbv3 "google.golang.org/grpc/reflection/grpc_testing_not_regenerate" 46 ) 47 48 var ( 49 s = NewServerV1(ServerOptions{}).(*serverReflectionServer) 50 // fileDescriptor of each test proto file. 51 fdProto2Ext *descriptorpb.FileDescriptorProto 52 fdProto2Ext2 *descriptorpb.FileDescriptorProto 53 fdDynamic *descriptorpb.FileDescriptorProto 54 // reflection descriptors. 55 fdDynamicFile protoreflect.FileDescriptor 56 // fileDescriptor marshalled. 57 fdTestByte []byte 58 fdTestv3Byte []byte 59 fdProto2Byte []byte 60 fdProto2ExtByte []byte 61 fdProto2Ext2Byte []byte 62 fdDynamicByte []byte 63 ) 64 65 const defaultTestTimeout = 10 * time.Second 66 67 type x struct { 68 grpctest.Tester 69 } 70 71 func Test(t *testing.T) { 72 grpctest.RunSubTests(t, x{}) 73 } 74 75 func loadFileDesc(filename string) (*descriptorpb.FileDescriptorProto, []byte) { 76 fd, err := protoregistry.GlobalFiles.FindFileByPath(filename) 77 if err != nil { 78 panic(err) 79 } 80 fdProto := protodesc.ToFileDescriptorProto(fd) 81 b, err := proto.Marshal(fdProto) 82 if err != nil { 83 panic(fmt.Sprintf("failed to marshal fd: %v", err)) 84 } 85 return fdProto, b 86 } 87 88 func loadFileDescDynamic(b []byte) (*descriptorpb.FileDescriptorProto, protoreflect.FileDescriptor, []byte) { 89 m := new(descriptorpb.FileDescriptorProto) 90 if err := proto.Unmarshal(b, m); err != nil { 91 panic("failed to unmarshal dynamic proto raw descriptor") 92 } 93 94 fd, err := protodesc.NewFile(m, nil) 95 if err != nil { 96 panic(err) 97 } 98 99 err = protoregistry.GlobalFiles.RegisterFile(fd) 100 if err != nil { 101 panic(err) 102 } 103 104 for i := 0; i < fd.Messages().Len(); i++ { 105 m := fd.Messages().Get(i) 106 if err := protoregistry.GlobalTypes.RegisterMessage(dynamicpb.NewMessageType(m)); err != nil { 107 panic(err) 108 } 109 } 110 111 return m, fd, b 112 } 113 114 func init() { 115 _, fdTestByte = loadFileDesc("reflection/grpc_testing/test.proto") 116 _, fdTestv3Byte = loadFileDesc("testv3.proto") 117 _, fdProto2Byte = loadFileDesc("reflection/grpc_testing/proto2.proto") 118 fdProto2Ext, fdProto2ExtByte = loadFileDesc("reflection/grpc_testing/proto2_ext.proto") 119 fdProto2Ext2, fdProto2Ext2Byte = loadFileDesc("reflection/grpc_testing/proto2_ext2.proto") 120 fdDynamic, fdDynamicFile, fdDynamicByte = loadFileDescDynamic(pbv3.FileDynamicProtoRawDesc) 121 } 122 123 func (x) TestFileDescContainingExtension(t *testing.T) { 124 for _, test := range []struct { 125 st string 126 extNum int32 127 want *descriptorpb.FileDescriptorProto 128 }{ 129 {"grpc.testing.ToBeExtended", 13, fdProto2Ext}, 130 {"grpc.testing.ToBeExtended", 17, fdProto2Ext}, 131 {"grpc.testing.ToBeExtended", 19, fdProto2Ext}, 132 {"grpc.testing.ToBeExtended", 23, fdProto2Ext2}, 133 {"grpc.testing.ToBeExtended", 29, fdProto2Ext2}, 134 } { 135 fd, err := s.fileDescEncodingContainingExtension(test.st, test.extNum, map[string]bool{}) 136 if err != nil { 137 t.Errorf("fileDescContainingExtension(%q) return error: %v", test.st, err) 138 continue 139 } 140 var actualFd descriptorpb.FileDescriptorProto 141 if err := proto.Unmarshal(fd[0], &actualFd); err != nil { 142 t.Errorf("fileDescContainingExtension(%q) return invalid bytes: %v", test.st, err) 143 continue 144 } 145 if !proto.Equal(&actualFd, test.want) { 146 t.Errorf("fileDescContainingExtension(%q) returned %q, but wanted %q", test.st, &actualFd, 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) TestAllExtensionNumbersForTypeName(t *testing.T) { 159 for _, test := range []struct { 160 st string 161 want []int32 162 }{ 163 {"grpc.testing.ToBeExtended", []int32{13, 17, 19, 23, 29}}, 164 } { 165 r, err := s.allExtensionNumbersForTypeName(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 func (x) TestFileDescWithDependencies(t *testing.T) { 174 depFile, err := protodesc.NewFile( 175 &descriptorpb.FileDescriptorProto{ 176 Name: proto.String("dep.proto"), 177 }, nil, 178 ) 179 if err != nil { 180 t.Fatalf("unexpected error: %s", err) 181 } 182 183 deps := &protoregistry.Files{} 184 if err := deps.RegisterFile(depFile); err != nil { 185 t.Fatalf("unexpected error: %s", err) 186 } 187 188 rootFileProto := &descriptorpb.FileDescriptorProto{ 189 Name: proto.String("root.proto"), 190 Dependency: []string{ 191 "google/protobuf/descriptor.proto", 192 "reflection/grpc_testing/proto2_ext2.proto", 193 "dep.proto", 194 }, 195 } 196 197 // dep.proto is in deps; the other imports come from protoregistry.GlobalFiles 198 resolver := &combinedResolver{first: protoregistry.GlobalFiles, second: deps} 199 rootFile, err := protodesc.NewFile(rootFileProto, resolver) 200 if err != nil { 201 t.Fatalf("unexpected error: %s", err) 202 } 203 204 // Create a file hierarchy that contains a placeholder for dep.proto 205 placeholderDep := placeholderFile{depFile} 206 placeholderDeps := &protoregistry.Files{} 207 if err := placeholderDeps.RegisterFile(placeholderDep); err != nil { 208 t.Fatalf("unexpected error: %s", err) 209 } 210 resolver = &combinedResolver{first: protoregistry.GlobalFiles, second: placeholderDeps} 211 212 rootFileHasPlaceholderDep, err := protodesc.NewFile(rootFileProto, resolver) 213 if err != nil { 214 t.Fatalf("unexpected error: %s", err) 215 } 216 217 rootFileIsPlaceholder := placeholderFile{rootFile} 218 219 // Full transitive dependency graph of root.proto includes five files: 220 // - root.proto 221 // - google/protobuf/descriptor.proto 222 // - reflection/grpc_testing/proto2_ext2.proto 223 // - reflection/grpc_testing/proto2.proto 224 // - dep.proto 225 226 for _, test := range []struct { 227 name string 228 sent []string 229 root protoreflect.FileDescriptor 230 expect []string 231 }{ 232 { 233 name: "send_all", 234 root: rootFile, 235 // expect full transitive closure 236 expect: []string{ 237 "root.proto", 238 "google/protobuf/descriptor.proto", 239 "reflection/grpc_testing/proto2_ext2.proto", 240 "reflection/grpc_testing/proto2.proto", 241 "dep.proto", 242 }, 243 }, 244 { 245 name: "already_sent", 246 sent: []string{ 247 "root.proto", 248 "google/protobuf/descriptor.proto", 249 "reflection/grpc_testing/proto2_ext2.proto", 250 "reflection/grpc_testing/proto2.proto", 251 "dep.proto", 252 }, 253 root: rootFile, 254 // expect only the root to be re-sent 255 expect: []string{"root.proto"}, 256 }, 257 { 258 name: "some_already_sent", 259 sent: []string{ 260 "reflection/grpc_testing/proto2_ext2.proto", 261 "reflection/grpc_testing/proto2.proto", 262 }, 263 root: rootFile, 264 expect: []string{ 265 "root.proto", 266 "google/protobuf/descriptor.proto", 267 "dep.proto", 268 }, 269 }, 270 { 271 name: "root_is_placeholder", 272 root: rootFileIsPlaceholder, 273 // expect error, no files 274 }, 275 { 276 name: "placeholder_skipped", 277 root: rootFileHasPlaceholderDep, 278 // dep.proto is a placeholder so is skipped 279 expect: []string{ 280 "root.proto", 281 "google/protobuf/descriptor.proto", 282 "reflection/grpc_testing/proto2_ext2.proto", 283 "reflection/grpc_testing/proto2.proto", 284 }, 285 }, 286 { 287 name: "placeholder_skipped_and_some_sent", 288 sent: []string{ 289 "reflection/grpc_testing/proto2_ext2.proto", 290 "reflection/grpc_testing/proto2.proto", 291 }, 292 root: rootFileHasPlaceholderDep, 293 expect: []string{ 294 "root.proto", 295 "google/protobuf/descriptor.proto", 296 }, 297 }, 298 } { 299 t.Run(test.name, func(t *testing.T) { 300 s := NewServerV1(ServerOptions{}).(*serverReflectionServer) 301 302 sent := map[string]bool{} 303 for _, path := range test.sent { 304 sent[path] = true 305 } 306 307 descriptors, err := s.fileDescWithDependencies(test.root, sent) 308 if len(test.expect) == 0 { 309 // if we're not expecting any files then we're expecting an error 310 if err == nil { 311 t.Fatalf("expecting an error; instead got %d files", len(descriptors)) 312 } 313 return 314 } 315 316 checkDescriptorResults(t, descriptors, test.expect) 317 }) 318 } 319 } 320 321 func checkDescriptorResults(t *testing.T, descriptors [][]byte, expect []string) { 322 t.Helper() 323 if len(descriptors) != len(expect) { 324 t.Errorf("expected result to contain %d descriptor(s); instead got %d", len(expect), len(descriptors)) 325 } 326 names := map[string]struct{}{} 327 for i, desc := range descriptors { 328 var descProto descriptorpb.FileDescriptorProto 329 if err := proto.Unmarshal(desc, &descProto); err != nil { 330 t.Fatalf("could not unmarshal descriptor result #%d", i+1) 331 } 332 names[descProto.GetName()] = struct{}{} 333 } 334 actual := make([]string, 0, len(names)) 335 for name := range names { 336 actual = append(actual, name) 337 } 338 sort.Strings(actual) 339 sort.Strings(expect) 340 if !reflect.DeepEqual(actual, expect) { 341 t.Fatalf("expected file descriptors for %v; instead got %v", expect, actual) 342 } 343 } 344 345 type placeholderFile struct { 346 protoreflect.FileDescriptor 347 } 348 349 func (placeholderFile) IsPlaceholder() bool { 350 return true 351 } 352 353 type combinedResolver struct { 354 first, second protodesc.Resolver 355 } 356 357 func (r *combinedResolver) FindFileByPath(path string) (protoreflect.FileDescriptor, error) { 358 file, err := r.first.FindFileByPath(path) 359 if err == nil { 360 return file, nil 361 } 362 return r.second.FindFileByPath(path) 363 } 364 365 func (r *combinedResolver) FindDescriptorByName(name protoreflect.FullName) (protoreflect.Descriptor, error) { 366 desc, err := r.first.FindDescriptorByName(name) 367 if err == nil { 368 return desc, nil 369 } 370 return r.second.FindDescriptorByName(name) 371 } 372 373 // Do end2end tests. 374 375 type server struct { 376 pb.UnimplementedSearchServiceServer 377 } 378 379 func (s *server) Search(ctx context.Context, in *pb.SearchRequest) (*pb.SearchResponse, error) { 380 return &pb.SearchResponse{}, nil 381 } 382 383 func (s *server) StreamingSearch(stream pb.SearchService_StreamingSearchServer) error { 384 return nil 385 } 386 387 type serverV3 struct{} 388 389 func (s *serverV3) Search(ctx context.Context, in *pbv3.SearchRequestV3) (*pbv3.SearchResponseV3, error) { 390 return &pbv3.SearchResponseV3{}, nil 391 } 392 393 func (s *serverV3) StreamingSearch(stream pbv3.SearchServiceV3_StreamingSearchServer) error { 394 return nil 395 } 396 397 func (x) TestReflectionEnd2end(t *testing.T) { 398 // Start server. 399 lis, err := net.Listen("tcp", "localhost:0") 400 if err != nil { 401 t.Fatalf("failed to listen: %v", err) 402 } 403 s := grpc.NewServer() 404 pb.RegisterSearchServiceServer(s, &server{}) 405 pbv3.RegisterSearchServiceV3Server(s, &serverV3{}) 406 407 registerDynamicProto(s, fdDynamic, fdDynamicFile) 408 409 // Register reflection service on s. 410 Register(s) 411 go s.Serve(lis) 412 t.Cleanup(s.Stop) 413 414 // Create client. 415 conn, err := grpc.Dial(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) 416 if err != nil { 417 t.Fatalf("cannot connect to server: %v", err) 418 } 419 defer conn.Close() 420 421 clientV1 := v1reflectiongrpc.NewServerReflectionClient(conn) 422 clientV1Alpha := v1alphareflectiongrpc.NewServerReflectionClient(conn) 423 testCases := []struct { 424 name string 425 client v1reflectiongrpc.ServerReflectionClient 426 }{ 427 { 428 name: "v1", 429 client: clientV1, 430 }, 431 { 432 name: "v1alpha", 433 client: v1AlphaClientAdapter{stub: clientV1Alpha}, 434 }, 435 } 436 for _, testCase := range testCases { 437 c := testCase.client 438 t.Run(testCase.name, func(t *testing.T) { 439 ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) 440 defer cancel() 441 stream, err := c.ServerReflectionInfo(ctx, grpc.WaitForReady(true)) 442 if err != nil { 443 t.Fatalf("cannot get ServerReflectionInfo: %v", err) 444 } 445 446 testFileByFilenameTransitiveClosure(t, stream, true) 447 testFileByFilenameTransitiveClosure(t, stream, false) 448 testFileByFilename(t, stream) 449 testFileByFilenameError(t, stream) 450 testFileContainingSymbol(t, stream) 451 testFileContainingSymbolError(t, stream) 452 testFileContainingExtension(t, stream) 453 testFileContainingExtensionError(t, stream) 454 testAllExtensionNumbersOfType(t, stream) 455 testAllExtensionNumbersOfTypeError(t, stream) 456 testListServices(t, stream) 457 }) 458 } 459 } 460 461 func testFileByFilenameTransitiveClosure(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient, expectClosure bool) { 462 filename := "reflection/grpc_testing/proto2_ext2.proto" 463 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 464 MessageRequest: &v1reflectionpb.ServerReflectionRequest_FileByFilename{ 465 FileByFilename: filename, 466 }, 467 }); err != nil { 468 t.Fatalf("failed to send request: %v", err) 469 } 470 r, err := stream.Recv() 471 if err != nil { 472 // io.EOF is not ok. 473 t.Fatalf("failed to recv response: %v", err) 474 } 475 switch r.MessageResponse.(type) { 476 case *v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse: 477 if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[0], fdProto2Ext2Byte) { 478 t.Errorf("FileByFilename(%v)\nreceived: %q,\nwant: %q", filename, r.GetFileDescriptorResponse().FileDescriptorProto[0], fdProto2Ext2Byte) 479 } 480 if expectClosure { 481 if len(r.GetFileDescriptorResponse().FileDescriptorProto) != 2 { 482 t.Errorf("FileByFilename(%v) returned %v file descriptors, expected 2", filename, len(r.GetFileDescriptorResponse().FileDescriptorProto)) 483 } else if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[1], fdProto2Byte) { 484 t.Errorf("FileByFilename(%v)\nreceived: %q,\nwant: %q", filename, r.GetFileDescriptorResponse().FileDescriptorProto[1], fdProto2Byte) 485 } 486 } else if len(r.GetFileDescriptorResponse().FileDescriptorProto) != 1 { 487 t.Errorf("FileByFilename(%v) returned %v file descriptors, expected 1", filename, len(r.GetFileDescriptorResponse().FileDescriptorProto)) 488 } 489 default: 490 t.Errorf("FileByFilename(%v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", filename, r.MessageResponse) 491 } 492 } 493 494 func testFileByFilename(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient) { 495 for _, test := range []struct { 496 filename string 497 want []byte 498 }{ 499 {"reflection/grpc_testing/test.proto", fdTestByte}, 500 {"reflection/grpc_testing/proto2.proto", fdProto2Byte}, 501 {"reflection/grpc_testing/proto2_ext.proto", fdProto2ExtByte}, 502 {"dynamic.proto", fdDynamicByte}, 503 } { 504 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 505 MessageRequest: &v1reflectionpb.ServerReflectionRequest_FileByFilename{ 506 FileByFilename: test.filename, 507 }, 508 }); err != nil { 509 t.Fatalf("failed to send request: %v", err) 510 } 511 r, err := stream.Recv() 512 if err != nil { 513 // io.EOF is not ok. 514 t.Fatalf("failed to recv response: %v", err) 515 } 516 517 switch r.MessageResponse.(type) { 518 case *v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse: 519 if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) { 520 t.Errorf("FileByFilename(%v)\nreceived: %q,\nwant: %q", test.filename, r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) 521 } 522 default: 523 t.Errorf("FileByFilename(%v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", test.filename, r.MessageResponse) 524 } 525 } 526 } 527 528 func testFileByFilenameError(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient) { 529 for _, test := range []string{ 530 "test.poto", 531 "proo2.proto", 532 "proto2_et.proto", 533 } { 534 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 535 MessageRequest: &v1reflectionpb.ServerReflectionRequest_FileByFilename{ 536 FileByFilename: test, 537 }, 538 }); err != nil { 539 t.Fatalf("failed to send request: %v", err) 540 } 541 r, err := stream.Recv() 542 if err != nil { 543 // io.EOF is not ok. 544 t.Fatalf("failed to recv response: %v", err) 545 } 546 547 switch r.MessageResponse.(type) { 548 case *v1reflectionpb.ServerReflectionResponse_ErrorResponse: 549 default: 550 t.Errorf("FileByFilename(%v) = %v, want type <ServerReflectionResponse_ErrorResponse>", test, r.MessageResponse) 551 } 552 } 553 } 554 555 func testFileContainingSymbol(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient) { 556 for _, test := range []struct { 557 symbol string 558 want []byte 559 }{ 560 {"grpc.testing.SearchService", fdTestByte}, 561 {"grpc.testing.SearchService.Search", fdTestByte}, 562 {"grpc.testing.SearchService.StreamingSearch", fdTestByte}, 563 {"grpc.testing.SearchResponse", fdTestByte}, 564 {"grpc.testing.ToBeExtended", fdProto2Byte}, 565 // Test support package v3. 566 {"grpc.testingv3.SearchServiceV3", fdTestv3Byte}, 567 {"grpc.testingv3.SearchServiceV3.Search", fdTestv3Byte}, 568 {"grpc.testingv3.SearchServiceV3.StreamingSearch", fdTestv3Byte}, 569 {"grpc.testingv3.SearchResponseV3", fdTestv3Byte}, 570 // search for field, oneof, enum, and enum value symbols, too 571 {"grpc.testingv3.SearchResponseV3.Result.snippets", fdTestv3Byte}, 572 {"grpc.testingv3.SearchResponseV3.Result.Value.val", fdTestv3Byte}, 573 {"grpc.testingv3.SearchResponseV3.Result.Value.str", fdTestv3Byte}, 574 {"grpc.testingv3.SearchResponseV3.State", fdTestv3Byte}, 575 {"grpc.testingv3.SearchResponseV3.FRESH", fdTestv3Byte}, 576 // Test dynamic symbols 577 {"grpc.testing.DynamicService", fdDynamicByte}, 578 {"grpc.testing.DynamicReq", fdDynamicByte}, 579 {"grpc.testing.DynamicRes", fdDynamicByte}, 580 } { 581 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 582 MessageRequest: &v1reflectionpb.ServerReflectionRequest_FileContainingSymbol{ 583 FileContainingSymbol: test.symbol, 584 }, 585 }); err != nil { 586 t.Fatalf("failed to send request: %v", err) 587 } 588 r, err := stream.Recv() 589 if err != nil { 590 // io.EOF is not ok. 591 t.Fatalf("failed to recv response: %v", err) 592 } 593 594 switch r.MessageResponse.(type) { 595 case *v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse: 596 if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) { 597 t.Errorf("FileContainingSymbol(%v)\nreceived: %q,\nwant: %q", test.symbol, r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) 598 } 599 default: 600 t.Errorf("FileContainingSymbol(%v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", test.symbol, r.MessageResponse) 601 } 602 } 603 } 604 605 func testFileContainingSymbolError(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient) { 606 for _, test := range []string{ 607 "grpc.testing.SerchService", 608 "grpc.testing.SearchService.SearchE", 609 "grpc.tesing.SearchResponse", 610 "gpc.testing.ToBeExtended", 611 } { 612 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 613 MessageRequest: &v1reflectionpb.ServerReflectionRequest_FileContainingSymbol{ 614 FileContainingSymbol: test, 615 }, 616 }); err != nil { 617 t.Fatalf("failed to send request: %v", err) 618 } 619 r, err := stream.Recv() 620 if err != nil { 621 // io.EOF is not ok. 622 t.Fatalf("failed to recv response: %v", err) 623 } 624 625 switch r.MessageResponse.(type) { 626 case *v1reflectionpb.ServerReflectionResponse_ErrorResponse: 627 default: 628 t.Errorf("FileContainingSymbol(%v) = %v, want type <ServerReflectionResponse_ErrorResponse>", test, r.MessageResponse) 629 } 630 } 631 } 632 633 func testFileContainingExtension(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient) { 634 for _, test := range []struct { 635 typeName string 636 extNum int32 637 want []byte 638 }{ 639 {"grpc.testing.ToBeExtended", 13, fdProto2ExtByte}, 640 {"grpc.testing.ToBeExtended", 17, fdProto2ExtByte}, 641 {"grpc.testing.ToBeExtended", 19, fdProto2ExtByte}, 642 {"grpc.testing.ToBeExtended", 23, fdProto2Ext2Byte}, 643 {"grpc.testing.ToBeExtended", 29, fdProto2Ext2Byte}, 644 } { 645 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 646 MessageRequest: &v1reflectionpb.ServerReflectionRequest_FileContainingExtension{ 647 FileContainingExtension: &v1reflectionpb.ExtensionRequest{ 648 ContainingType: test.typeName, 649 ExtensionNumber: test.extNum, 650 }, 651 }, 652 }); err != nil { 653 t.Fatalf("failed to send request: %v", err) 654 } 655 r, err := stream.Recv() 656 if err != nil { 657 // io.EOF is not ok. 658 t.Fatalf("failed to recv response: %v", err) 659 } 660 661 switch r.MessageResponse.(type) { 662 case *v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse: 663 if !reflect.DeepEqual(r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) { 664 t.Errorf("FileContainingExtension(%v, %v)\nreceived: %q,\nwant: %q", test.typeName, test.extNum, r.GetFileDescriptorResponse().FileDescriptorProto[0], test.want) 665 } 666 default: 667 t.Errorf("FileContainingExtension(%v, %v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", test.typeName, test.extNum, r.MessageResponse) 668 } 669 } 670 } 671 672 func testFileContainingExtensionError(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient) { 673 for _, test := range []struct { 674 typeName string 675 extNum int32 676 }{ 677 {"grpc.testing.ToBExtended", 17}, 678 {"grpc.testing.ToBeExtended", 15}, 679 } { 680 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 681 MessageRequest: &v1reflectionpb.ServerReflectionRequest_FileContainingExtension{ 682 FileContainingExtension: &v1reflectionpb.ExtensionRequest{ 683 ContainingType: test.typeName, 684 ExtensionNumber: test.extNum, 685 }, 686 }, 687 }); err != nil { 688 t.Fatalf("failed to send request: %v", err) 689 } 690 r, err := stream.Recv() 691 if err != nil { 692 // io.EOF is not ok. 693 t.Fatalf("failed to recv response: %v", err) 694 } 695 696 switch r.MessageResponse.(type) { 697 case *v1reflectionpb.ServerReflectionResponse_ErrorResponse: 698 default: 699 t.Errorf("FileContainingExtension(%v, %v) = %v, want type <ServerReflectionResponse_FileDescriptorResponse>", test.typeName, test.extNum, r.MessageResponse) 700 } 701 } 702 } 703 704 func testAllExtensionNumbersOfType(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient) { 705 for _, test := range []struct { 706 typeName string 707 want []int32 708 }{ 709 {"grpc.testing.ToBeExtended", []int32{13, 17, 19, 23, 29}}, 710 {"grpc.testing.DynamicReq", nil}, 711 } { 712 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 713 MessageRequest: &v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ 714 AllExtensionNumbersOfType: test.typeName, 715 }, 716 }); err != nil { 717 t.Fatalf("failed to send request: %v", err) 718 } 719 r, err := stream.Recv() 720 if err != nil { 721 // io.EOF is not ok. 722 t.Fatalf("failed to recv response: %v", err) 723 } 724 725 switch r.MessageResponse.(type) { 726 case *v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse: 727 extNum := r.GetAllExtensionNumbersResponse().ExtensionNumber 728 sort.Sort(intArray(extNum)) 729 if r.GetAllExtensionNumbersResponse().BaseTypeName != test.typeName || 730 !reflect.DeepEqual(extNum, test.want) { 731 t.Errorf("AllExtensionNumbersOfType(%v)\nreceived: %v,\nwant: {%q %v}", r.GetAllExtensionNumbersResponse(), test.typeName, test.typeName, test.want) 732 } 733 default: 734 t.Errorf("AllExtensionNumbersOfType(%v) = %v, want type <ServerReflectionResponse_AllExtensionNumbersResponse>", test.typeName, r.MessageResponse) 735 } 736 } 737 } 738 739 func testAllExtensionNumbersOfTypeError(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient) { 740 for _, test := range []string{ 741 "grpc.testing.ToBeExtendedE", 742 } { 743 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 744 MessageRequest: &v1reflectionpb.ServerReflectionRequest_AllExtensionNumbersOfType{ 745 AllExtensionNumbersOfType: test, 746 }, 747 }); err != nil { 748 t.Fatalf("failed to send request: %v", err) 749 } 750 r, err := stream.Recv() 751 if err != nil { 752 // io.EOF is not ok. 753 t.Fatalf("failed to recv response: %v", err) 754 } 755 756 switch r.MessageResponse.(type) { 757 case *v1reflectionpb.ServerReflectionResponse_ErrorResponse: 758 default: 759 t.Errorf("AllExtensionNumbersOfType(%v) = %v, want type <ServerReflectionResponse_ErrorResponse>", test, r.MessageResponse) 760 } 761 } 762 } 763 764 func testListServices(t *testing.T, stream v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient) { 765 if err := stream.Send(&v1reflectionpb.ServerReflectionRequest{ 766 MessageRequest: &v1reflectionpb.ServerReflectionRequest_ListServices{}, 767 }); err != nil { 768 t.Fatalf("failed to send request: %v", err) 769 } 770 r, err := stream.Recv() 771 if err != nil { 772 // io.EOF is not ok. 773 t.Fatalf("failed to recv response: %v", err) 774 } 775 776 switch r.MessageResponse.(type) { 777 case *v1reflectionpb.ServerReflectionResponse_ListServicesResponse: 778 services := r.GetListServicesResponse().Service 779 want := []string{ 780 "grpc.testingv3.SearchServiceV3", 781 "grpc.testing.SearchService", 782 "grpc.reflection.v1.ServerReflection", 783 "grpc.reflection.v1alpha.ServerReflection", 784 "grpc.testing.DynamicService", 785 } 786 // Compare service names in response with want. 787 if len(services) != len(want) { 788 t.Errorf("= %v, want service names: %v", services, want) 789 } 790 m := make(map[string]int) 791 for _, e := range services { 792 m[e.Name]++ 793 } 794 for _, e := range want { 795 if m[e] > 0 { 796 m[e]-- 797 continue 798 } 799 t.Errorf("ListService\nreceived: %v,\nwant: %q", services, want) 800 } 801 default: 802 t.Errorf("ListServices = %v, want type <ServerReflectionResponse_ListServicesResponse>", r.MessageResponse) 803 } 804 } 805 806 func registerDynamicProto(srv *grpc.Server, fdp *descriptorpb.FileDescriptorProto, fd protoreflect.FileDescriptor) { 807 type emptyInterface any 808 809 for i := 0; i < fd.Services().Len(); i++ { 810 s := fd.Services().Get(i) 811 812 sd := &grpc.ServiceDesc{ 813 ServiceName: string(s.FullName()), 814 HandlerType: (*emptyInterface)(nil), 815 Metadata: fdp.GetName(), 816 } 817 818 for j := 0; j < s.Methods().Len(); j++ { 819 m := s.Methods().Get(j) 820 sd.Methods = append(sd.Methods, grpc.MethodDesc{ 821 MethodName: string(m.Name()), 822 }) 823 } 824 825 srv.RegisterService(sd, struct{}{}) 826 } 827 } 828 829 type v1AlphaClientAdapter struct { 830 stub v1alphareflectiongrpc.ServerReflectionClient 831 } 832 833 func (v v1AlphaClientAdapter) ServerReflectionInfo(ctx context.Context, opts ...grpc.CallOption) (v1reflectiongrpc.ServerReflection_ServerReflectionInfoClient, error) { 834 stream, err := v.stub.ServerReflectionInfo(ctx, opts...) 835 if err != nil { 836 return nil, err 837 } 838 return v1AlphaClientStreamAdapter{stream}, nil 839 } 840 841 type v1AlphaClientStreamAdapter struct { 842 v1alphareflectiongrpc.ServerReflection_ServerReflectionInfoClient 843 } 844 845 func (s v1AlphaClientStreamAdapter) Send(request *v1reflectionpb.ServerReflectionRequest) error { 846 return s.ServerReflection_ServerReflectionInfoClient.Send(v1ToV1AlphaRequest(request)) 847 } 848 849 func (s v1AlphaClientStreamAdapter) Recv() (*v1reflectionpb.ServerReflectionResponse, error) { 850 resp, err := s.ServerReflection_ServerReflectionInfoClient.Recv() 851 if err != nil { 852 return nil, err 853 } 854 return v1AlphaToV1Response(resp), nil 855 } 856 857 func v1AlphaToV1Response(v1alpha *v1alphareflectionpb.ServerReflectionResponse) *v1reflectionpb.ServerReflectionResponse { 858 var v1 v1reflectionpb.ServerReflectionResponse 859 v1.ValidHost = v1alpha.ValidHost 860 if v1alpha.OriginalRequest != nil { 861 v1.OriginalRequest = v1AlphaToV1Request(v1alpha.OriginalRequest) 862 } 863 switch mr := v1alpha.MessageResponse.(type) { 864 case *v1alphareflectionpb.ServerReflectionResponse_FileDescriptorResponse: 865 if mr != nil { 866 v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_FileDescriptorResponse{ 867 FileDescriptorResponse: &v1reflectionpb.FileDescriptorResponse{ 868 FileDescriptorProto: mr.FileDescriptorResponse.GetFileDescriptorProto(), 869 }, 870 } 871 } 872 case *v1alphareflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse: 873 if mr != nil { 874 v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_AllExtensionNumbersResponse{ 875 AllExtensionNumbersResponse: &v1reflectionpb.ExtensionNumberResponse{ 876 BaseTypeName: mr.AllExtensionNumbersResponse.GetBaseTypeName(), 877 ExtensionNumber: mr.AllExtensionNumbersResponse.GetExtensionNumber(), 878 }, 879 } 880 } 881 case *v1alphareflectionpb.ServerReflectionResponse_ListServicesResponse: 882 if mr != nil { 883 svcs := make([]*v1reflectionpb.ServiceResponse, len(mr.ListServicesResponse.GetService())) 884 for i, svc := range mr.ListServicesResponse.GetService() { 885 svcs[i] = &v1reflectionpb.ServiceResponse{ 886 Name: svc.GetName(), 887 } 888 } 889 v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ListServicesResponse{ 890 ListServicesResponse: &v1reflectionpb.ListServiceResponse{ 891 Service: svcs, 892 }, 893 } 894 } 895 case *v1alphareflectionpb.ServerReflectionResponse_ErrorResponse: 896 if mr != nil { 897 v1.MessageResponse = &v1reflectionpb.ServerReflectionResponse_ErrorResponse{ 898 ErrorResponse: &v1reflectionpb.ErrorResponse{ 899 ErrorCode: mr.ErrorResponse.GetErrorCode(), 900 ErrorMessage: mr.ErrorResponse.GetErrorMessage(), 901 }, 902 } 903 } 904 default: 905 // no value set 906 } 907 return &v1 908 }