1 #region Copyright notice and license 2 // Copyright 2015 gRPC authors. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 #endregion 16 17 using System; 18 using System.Collections.Generic; 19 using System.Linq; 20 using System.Text; 21 using System.Threading.Tasks; 22 23 using Grpc.Core; 24 using Grpc.Reflection; 25 using Grpc.Reflection.V1Alpha; 26 using NUnit.Framework; 27 28 namespace Grpc.Reflection.Tests 29 { 30 /// <summary> 31 /// Reflection client talks to reflection server. 32 /// </summary> 33 public class ReflectionClientServerTest 34 { 35 const string Host = "localhost"; 36 Server server; 37 Channel channel; 38 ServerReflection.ServerReflectionClient client; 39 ReflectionServiceImpl serviceImpl; 40 41 [OneTimeSetUp] Init()42 public void Init() 43 { 44 serviceImpl = new ReflectionServiceImpl(ServerReflection.Descriptor); 45 46 // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755 47 server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) 48 { 49 Services = { ServerReflection.BindService(serviceImpl) }, 50 Ports = { { Host, ServerPort.PickUnused, ServerCredentials.Insecure } } 51 }; 52 server.Start(); 53 channel = new Channel(Host, server.Ports.Single().BoundPort, ChannelCredentials.Insecure); 54 55 client = new ServerReflection.ServerReflectionClient(channel); 56 } 57 58 [OneTimeTearDown] Cleanup()59 public void Cleanup() 60 { 61 channel.ShutdownAsync().Wait(); 62 server.ShutdownAsync().Wait(); 63 } 64 65 [Test] FileByFilename_NotFound()66 public async Task FileByFilename_NotFound() 67 { 68 var response = await SingleRequestAsync(new ServerReflectionRequest 69 { 70 FileByFilename = "somepackage/nonexistent.proto" 71 }); 72 Assert.AreEqual((int)StatusCode.NotFound, response.ErrorResponse.ErrorCode); 73 } 74 75 [Test] FileByFilename()76 public async Task FileByFilename() 77 { 78 var response = await SingleRequestAsync(new ServerReflectionRequest 79 { 80 FileByFilename = "grpc/reflection/v1alpha/reflection.proto" 81 }); 82 Assert.AreEqual(1, response.FileDescriptorResponse.FileDescriptorProto.Count); 83 Assert.AreEqual(ReflectionReflection.Descriptor.SerializedData, response.FileDescriptorResponse.FileDescriptorProto[0]); 84 } 85 86 [Test] FileContainingSymbol()87 public async Task FileContainingSymbol() 88 { 89 var response = await SingleRequestAsync(new ServerReflectionRequest 90 { 91 FileContainingSymbol = "grpc.reflection.v1alpha.ServerReflection" 92 }); 93 Assert.AreEqual(1, response.FileDescriptorResponse.FileDescriptorProto.Count); 94 Assert.AreEqual(ReflectionReflection.Descriptor.SerializedData, response.FileDescriptorResponse.FileDescriptorProto[0]); 95 } 96 97 [Test] FileContainingSymbol_NotFound()98 public async Task FileContainingSymbol_NotFound() 99 { 100 var response = await SingleRequestAsync(new ServerReflectionRequest 101 { 102 FileContainingSymbol = "somepackage.Nonexistent" 103 }); 104 Assert.AreEqual((int)StatusCode.NotFound, response.ErrorResponse.ErrorCode); 105 } 106 107 [Test] ListServices()108 public async Task ListServices() 109 { 110 var response = await SingleRequestAsync(new ServerReflectionRequest 111 { 112 ListServices = "" 113 }); 114 Assert.AreEqual(1, response.ListServicesResponse.Service.Count); 115 Assert.AreEqual(ServerReflection.Descriptor.FullName, response.ListServicesResponse.Service[0].Name); 116 } 117 118 [Test] FileContainingExtension()119 public async Task FileContainingExtension() 120 { 121 var response = await SingleRequestAsync(new ServerReflectionRequest 122 { 123 FileContainingExtension = new ExtensionRequest() 124 }); 125 Assert.AreEqual((int)StatusCode.Unimplemented, response.ErrorResponse.ErrorCode); 126 } 127 SingleRequestAsync(ServerReflectionRequest request)128 private async Task<ServerReflectionResponse> SingleRequestAsync(ServerReflectionRequest request) 129 { 130 var call = client.ServerReflectionInfo(); 131 await call.RequestStream.WriteAsync(request); 132 Assert.IsTrue(await call.ResponseStream.MoveNext()); 133 134 var response = call.ResponseStream.Current; 135 await call.RequestStream.CompleteAsync(); 136 Assert.IsFalse(await call.ResponseStream.MoveNext()); 137 return response; 138 } 139 } 140 } 141