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