ExternalDnsWithTracingClientServerTest.cs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #region Copyright notice and license
  2. // Copyright 2019 The 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. using System;
  17. using System.Collections.Generic;
  18. using System.Net.Sockets;
  19. using System.Linq;
  20. using System.Threading;
  21. using System.Threading.Tasks;
  22. using Grpc.Core;
  23. using Grpc.Core.Logging;
  24. using Grpc.Core.Utils;
  25. using Grpc.Testing;
  26. using NUnit.Framework;
  27. namespace Grpc.IntegrationTesting
  28. {
  29. /// <summary>
  30. /// See https://github.com/grpc/issues/18074, this test is meant to
  31. /// try to trigger the described bug.
  32. /// Runs interop tests in-process, with that client using a target
  33. /// name that using a target name that triggers interaction with
  34. /// external DNS servers (even though it resolves to the in-proc server).
  35. /// </summary>
  36. public class ExternalDnsWithTracingClientServerTest
  37. {
  38. Server server;
  39. Channel channel;
  40. TestService.TestServiceClient client;
  41. SocketUsingLogger newLogger;
  42. [OneTimeSetUp]
  43. public void Init()
  44. {
  45. // TODO(https://github.com/grpc/grpc/issues/14963): on linux, setting
  46. // these environment variables might not actually have any affect.
  47. // This is OK because we only really care about running this test on
  48. // Windows, however, a fix made for $14963 should be applied here.
  49. Environment.SetEnvironmentVariable("GRPC_TRACE", "all");
  50. Environment.SetEnvironmentVariable("GRPC_VERBOSITY", "DEBUG");
  51. newLogger = new SocketUsingLogger(GrpcEnvironment.Logger);
  52. GrpcEnvironment.SetLogger(newLogger);
  53. // Disable SO_REUSEPORT to prevent https://github.com/grpc/grpc/issues/10755
  54. server = new Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
  55. {
  56. Services = { TestService.BindService(new TestServiceImpl()) },
  57. Ports = { { "[::1]", ServerPort.PickUnused, ServerCredentials.Insecure } }
  58. };
  59. server.Start();
  60. int port = server.Ports.Single().BoundPort;
  61. channel = new Channel("loopback6.unittest.grpc.io", port, ChannelCredentials.Insecure);
  62. client = new TestService.TestServiceClient(channel);
  63. }
  64. [OneTimeTearDown]
  65. public void Cleanup()
  66. {
  67. channel.ShutdownAsync().Wait();
  68. server.ShutdownAsync().Wait();
  69. }
  70. [Test]
  71. public void EmptyUnary()
  72. {
  73. InteropClient.RunEmptyUnary(client);
  74. }
  75. }
  76. /// <summary>
  77. /// Logger which does some socket operation after delegating
  78. /// actual logging to its delegate logger. The main goal is to
  79. /// reset the current thread's WSA error status.
  80. /// The only reason for the delegateLogger is to continue
  81. /// to have this test display debug logs.
  82. /// </summary>
  83. internal sealed class SocketUsingLogger : ILogger
  84. {
  85. private ILogger delegateLogger;
  86. public SocketUsingLogger(ILogger delegateLogger) {
  87. this.delegateLogger = delegateLogger;
  88. }
  89. public void Debug(string message)
  90. {
  91. MyLog(() => delegateLogger.Debug(message));
  92. }
  93. public void Debug(string format, params object[] formatArgs)
  94. {
  95. MyLog(() => delegateLogger.Debug(format, formatArgs));
  96. }
  97. public void Error(string message)
  98. {
  99. MyLog(() => delegateLogger.Error(message));
  100. }
  101. public void Error(Exception exception, string message)
  102. {
  103. MyLog(() => delegateLogger.Error(exception, message));
  104. }
  105. public void Error(string format, params object[] formatArgs)
  106. {
  107. MyLog(() => delegateLogger.Error(format, formatArgs));
  108. }
  109. public ILogger ForType<T>()
  110. {
  111. return this;
  112. }
  113. public void Info(string message)
  114. {
  115. MyLog(() => delegateLogger.Info(message));
  116. }
  117. public void Info(string format, params object[] formatArgs)
  118. {
  119. MyLog(() => delegateLogger.Info(format, formatArgs));
  120. }
  121. public void Warning(string message)
  122. {
  123. MyLog(() => delegateLogger.Warning(message));
  124. }
  125. public void Warning(Exception exception, string message)
  126. {
  127. MyLog(() => delegateLogger.Warning(exception, message));
  128. }
  129. public void Warning(string format, params object[] formatArgs)
  130. {
  131. MyLog(() => delegateLogger.Warning(format, formatArgs));
  132. }
  133. private void MyLog(Action delegateLog)
  134. {
  135. delegateLog();
  136. // Create and close a socket, just in order to affect
  137. // the WSA (on Windows) error status of the current thread.
  138. Socket s = new Socket(AddressFamily.InterNetwork,
  139. SocketType.Stream,
  140. ProtocolType.Tcp);
  141. s.Dispose();
  142. }
  143. }
  144. }